diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..9995802 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"] +} \ No newline at end of file diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 0000000..3a64c11 --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,91 @@ +name: "Java CI" +on: + push: + branches: + - master + - '[0-9]+.x' + pull_request: + branches: + - master + - '[0-9]+.x' + workflow_dispatch: +permissions: + packages: read +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false +jobs: + tests: + if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }} + name: "Test" + runs-on: ubuntu-24.04 + container: ubuntu + services: + postgres: + image: postgres + env: + POSTGRES_DB: pg_extensions_test + POSTGRES_USER: postgres_extensions + POSTGRES_PASSWORD: postgres_extensions + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U postgres_extensions -d pg_extensions_test" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + - name: Install psql client + env: + DEBIAN_FRONTEND: noninteractive + run: | + apt-get update + apt-get install -y --no-install-recommends postgresql-client + - name: Create extensions + env: + PGPASSWORD: postgres_extensions + run: | + until pg_isready -h postgres -p 5432 -U postgres_extensions -d pg_extensions_test; do sleep 1; done + psql -h postgres -U postgres_extensions -d pg_extensions_test -c "CREATE EXTENSION IF NOT EXISTS hstore;" + - name: "📥 Checkout repository" + uses: actions/checkout@v5 + - name: "☕️ Setup JDK" + uses: actions/setup-java@v5 + with: + java-version: 17 + distribution: liberica + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "🏃‍♂️ Run Checks" + id: build + env: + POSTGRES_HOST: postgres + POSTGRES_PORT: 5432 + run: ./gradlew check --continue + publish_snapshot: + needs: tests + if: ${{ always() && github.repository_owner == 'gpc' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (needs.tests.result == 'success' || needs.tests.result == 'skipped') }} + runs-on: ubuntu-24.04 + permissions: + contents: write + steps: + - name: "📥 Checkout repository" + uses: actions/checkout@v4 + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: liberica + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "📤 Publish Snapshot Artifacts" + env: + GRAILS_PUBLISH_RELEASE: 'false' + MAVEN_PUBLISH_URL: ${{ secrets.MAVEN_PUBLISH_SNAPSHOT_URL }} + MAVEN_PUBLISH_USERNAME: ${{ secrets.MAVEN_PUBLISH_USERNAME }} + MAVEN_PUBLISH_PASSWORD: ${{ secrets.MAVEN_PUBLISH_PASSWORD }} + run: ./gradlew --no-build-cache publish \ No newline at end of file diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml new file mode 100644 index 0000000..2ae8559 --- /dev/null +++ b/.github/workflows/release-notes.yml @@ -0,0 +1,24 @@ +name: "Release Drafter" +on: + issues: + types: [closed, reopened] + push: + branches: + - 'master' + - '[0-9]+.x' + pull_request: + types: [opened, reopened, synchronize] + pull_request_target: + types: [opened, reopened, synchronize] + workflow_dispatch: +jobs: + update_release_draft: + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-24.04 + steps: + - name: "📝 Update Release Draft" + uses: release-drafter/release-drafter@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..9cc7c12 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,135 @@ +name: Release +on: + release: + types: [ published ] +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + JAVA_VERSION: '17.0.15' # this must be a specific version for reproducible builds + RELEASE_TAG_PREFIX: 'v' +jobs: + publish: + permissions: + packages: read # pre-release workflow + contents: write # to create release + issues: write # to modify milestones + runs-on: ubuntu-24.04 + outputs: + release_version: ${{ steps.release_version.outputs.value }} + extract_repository_name: ${{ steps.extract_repository_name.outputs.repository_name }} + steps: + - name: "📝 Store the current release version" + id: release_version + run: | + export RELEASE_VERSION="${{ github.ref_name }}" + export RELEASE_VERSION=${RELEASE_VERSION:${#RELEASE_TAG_PREFIX}} + echo "Found Release Version: ${RELEASE_VERSION}" + echo "value=${RELEASE_VERSION}" >> $GITHUB_OUTPUT + - name: "Extract repository name" + id: extract_repository_name + run: | + echo "repository_name=${GITHUB_REPOSITORY##*/}" >> $GITHUB_OUTPUT + - name: "📥 Checkout the repository" + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: v${{ steps.release_version.outputs.value }} + - name: 'Ensure Common Build Date' # to ensure a reproducible build + run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" + - name: "Ensure source files use common date" + run: | + find . -depth \( -type f -o -type d \) -exec touch -d "@${SOURCE_DATE_EPOCH}" {} + + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: liberica + java-version: ${{ env.JAVA_VERSION }} + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + with: + develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + - name: "⚙️ Run pre-release" + uses: apache/grails-github-actions/pre-release@asf + env: + RELEASE_VERSION: ${{ steps.release_version.outputs.value }} + - name: "🔐 Generate key file for artifact signing" + env: + SECRING_FILE: ${{ secrets.SECRING_FILE }} + run: | + printf "%s" "$SECRING_FILE" | base64 -d > "${{ github.workspace }}/secring.gpg" + - name: "🧩 Run Assemble" + id: assemble + run: | + ./gradlew -U assemble -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg -Psigning.keyId=${{ secrets.SIGNING_KEY }} + env: + GRAILS_PUBLISH_RELEASE: 'true' + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} + - name: "📤 Publish to Maven Central" + env: + GRAILS_PUBLISH_RELEASE: 'true' + NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_PUBLISH_USERNAME }} + NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_PUBLISH_PASSWORD }} + NEXUS_PUBLISH_URL: ${{ secrets.NEXUS_PUBLISH_RELEASE_URL }} + NEXUS_PUBLISH_DESCRIPTION: '${{ steps.extract_repository_name.outputs.repository_name }}:${{ steps.release_version.outputs.value }}' + SIGNING_KEY: ${{ secrets.SIGNING_KEY }} + SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }} + run: > + ./gradlew + -Psigning.keyId=${{ secrets.SIGNING_KEY }} + -Psigning.secretKeyRingFile=${{ github.workspace }}/secring.gpg + publishMavenPublicationToSonatypeRepository + closeSonatypeStagingRepository + - name: "Generate Build Date file" + run: echo "$SOURCE_DATE_EPOCH" >> build/BUILD_DATE.txt + - name: "Upload Build Date file" + uses: softprops/action-gh-release@da05d552573ad5aba039eaac05058a918a7bf631 + with: + tag_name: ${{ github.event.release.tag_name }} + files: build/BUILD_DATE.txt + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + release: + needs: publish + runs-on: ubuntu-24.04 + environment: release + permissions: + contents: write + issues: write + pull-requests: write + steps: + - name: "📥 Checkout repository" + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ref: v${{ needs.publish.outputs.release_version }} + - name: "☕️ Setup JDK" + uses: actions/setup-java@v4 + with: + distribution: liberica + java-version: ${{ env.JAVA_VERSION }} + - name: "🐘 Setup Gradle" + uses: gradle/actions/setup-gradle@v4 + - name: "📤 Release staging repository" + env: + GRAILS_PUBLISH_RELEASE: 'true' + NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_PUBLISH_USERNAME }} + NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_PUBLISH_PASSWORD }} + NEXUS_PUBLISH_URL: ${{ secrets.NEXUS_PUBLISH_RELEASE_URL }} + NEXUS_PUBLISH_DESCRIPTION: '${{ needs.publish.outputs.extract_repository_name }}:${{ needs.publish.outputs.release_version }}' + run: > + ./gradlew + findSonatypeStagingRepository + releaseSonatypeStagingRepository + - name: "📖 Generate Documentation" + if: ${{ hashFiles('src/main/asciidoc/**') != '' }} + run: ./gradlew docs + - name: "📤 Publish Documentation to Github Pages" + uses: apache/grails-github-actions/deploy-github-pages@asf + if: ${{ hashFiles('src/main/asciidoc/**') != '' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GRADLE_PUBLISH_RELEASE: 'true' + SOURCE_FOLDER: build/docs + VERSION: ${{ needs.publish.outputs.release_version }} + - name: "⚙️ Run post-release" + uses: apache/grails-github-actions/post-release@asf diff --git a/.gitignore b/.gitignore index db7d75a..bae7029 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ plugin.xml grails-postgresql-extensions-*.zip grails-postgresql-extensions-*.zip.sha1 /.idea +!/.idea/codeStyles +!.idea/codeStyles/Project.xml +!.idea/codeStyles/codeStyleConfig.xml *.iml *.swp *.ids diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..3f19036 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..52768fe --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/.sdkmanrc b/.sdkmanrc new file mode 100644 index 0000000..48cc71b --- /dev/null +++ b/.sdkmanrc @@ -0,0 +1,2 @@ +# Enable auto-env through the sdkman_auto_env config - https://sdkman.io/usage#env +java=17.0.15-librca diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4ceeff3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -dist: precise -sudo: required -language: groovy -jdk: - - oraclejdk8 - -env: - global: - - GIT_NAME="Iván López" - - GIT_EMAIL="lopez.ivan@gmail.com" - - secure: qdvGtJFbtvTJPZ9HbBC4DtPGLAeWQq5A1gX7u4xxfPBNw/Mkd7Z0/OrWiMuNMccDvqhiPAbauZRb3ZSE/KOWhqSKg6EAMeQpBgGUOrjXNBH6x0m2BthFkQhEVWrDVqGx+AuEbm7kRsNw6ec+kJ6oaBPjnHOfbPnGVro+4sGWSck= - - secure: ZYo6fjlQNV1Oyc+fcINeISvR3pUAQG/V9I28v0xs2hjDiAug4gPnaQgxhmpa1SfRo5vwk+Oi+eNG22K2ePmUqARz2K5REahEPvocRZwrEow7pvJGvsLwiDcJk/o20fLPcUJlxgAyJeOQYR+exg35TlfHQ0ZWPVj07HO/A+1KTeM= - -addons: - postgresql: "9.4" - -sudo: false - -before_script: - - psql -d template1 -c 'create extension hstore;' -U postgres - - psql -c 'create database pg_extensions_test;' -U postgres - - psql -c "create user postgres_extensions with password 'postgres_extensions';" -U postgres - - psql -c "grant all privileges on database pg_extensions_test to postgres_extensions;" -U postgres - - rm -rf target - -script: - - ./travis-build.sh - -notifications: - email: - recipients: - - lopez.ivan@gmail.com - - alonso.javier.torres@gmail.com - - on_success: change - on_failure: change - -#after_success: -# - ./gradlew cobertura coveralls diff --git a/Makefile b/Makefile deleted file mode 100644 index eee89a1..0000000 --- a/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: test - -image : - docker build -f Dockerfile -t grails/postgres-extensions . - -clean : - docker rmi -f grails/postgres-extensions - -test : - ./gradlew clean - docker run --rm --name pg_extensions_test -p 5432:5432 -d grails/postgres-extensions - ./gradlew check - docker container kill pg_extensions_test - -all : image test \ No newline at end of file diff --git a/README.md b/README.md index dd931b4..17ffe9a 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,13 @@ -# ⚠️ This plugin is not maintained anymore ⚠️ +# Grails PostgreSQL Extensions -## Grails Postgresql Extensions +This is a Grails plugin that provides Hibernate user types to use PostgreSQL native types such as Array, Hstore, Json, +Jsonb, ..., from a Grails application. It also provides new criteria to query these new native types. -#### THIS BRANCH (master) IS FOR GRAILS 4 AND HIBERNATE 5.4 #### - -This is a grails plugin that provides hibernate user types to use Postgresql native types such as Array, Hstore, Json, -Jsonb... from a Grails application. It also provides new criterias to query this new native types. - -Currently the plugin supports array, hstore, json and jsonb fields as well as some query methods. +Currently, the plugin supports array, hstore, json and jsonb fields as well as some query methods. More native types and query methods will be added in the future. * [Installation](#installation) - * [Postgresql driver](#postgresql-driver) + * [PostgreSQL driver](#postgresql-driver) * [Hibernate plugin](#hibernate-plugin) * [Configuration](#configuration) * [Native Types](#native-types) @@ -46,90 +42,26 @@ More native types and query methods will be added in the future. * [Order](#order) * [Random order](#random-order) * [Sql formula](#sql-formula) -* [Authors](#authors) * [Release Notes](#release-notes) ## Installation -The Grails 3 version supports both Hibernate 4.X (versions 4.x.x of the plugin) and Hibernate 5.X (versions 5.x.x of the -plugin). In `build.gradle` add the `jcenter` repository and the following dependency to install the plugin: - +The Grails 7 version of this plugin supports Hibernate 5. +In `build.gradle` add the following dependencies to install the plugin: ```groovy -repositories { - ... - jcenter() - ... -} - dependencies { - ... - compile 'org.grails.plugins:postgresql-extensions:' - ... -} -``` - -### Postgresql driver - -You also need to install the Postgresql jdbc driver. You can see all available Postgresql jdbc libraries versions at -[MVN Repository](http://mvnrepository.com/artifact/org.postgresql/postgresql). - -```groovy -dependencies { - ... - provided 'org.postgresql:postgresql:9.4.1211.jre7' - ... -} -``` - -### Hibernate plugin - -It's also necessary to install the Grails-Hibernate plugin. Depending if you use Hibernate 4 or Hibernate 5 you'll need -different dependencies. Please make sure you use the latest versions of the plugin and the hibernate dependencies - - -```groovy -// Hibernate 4 -buildscript { - ... - dependencies { - ... - classpath "org.grails.plugins:hibernate4:6.0.3" - } -} - -dependencies { - ... - compile "org.grails.plugins:hibernate4" - compile "org.hibernate:hibernate-core:4.3.11.Final" - compile "org.hibernate:hibernate-ehcache:4.3.11.Final" - ... -} -``` - -```groovy -// Hibernate 5 -buildscript { - ... - dependencies { - ... - classpath "org.grails.plugins:hibernate5:6.0.3" - } -} - -dependencies { - ... - compile "org.grails.plugins:hibernate5" - compile "org.hibernate:hibernate-core:5.1.1.Final" - compile "org.hibernate:hibernate-ehcache:5.1.1.Final" - ... + //... + implementation 'io.github.gpc:grails-postgresql-extensions:' + implementation 'org.apache.grails:grails-data-hibernate5' + //... } ``` ## Configuration -After install the plugin you have to use a new Postgresql Hibernate Dialect in your application. Add it to the +After installing the plugin you have to use a new PostgreSQL Hibernate Dialect in your application. Add it to the `grails-app/conf/application.yml` file: ```yaml @@ -144,24 +76,16 @@ dataSource: dbCreate: update hibernate: - dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect + dialect: gpc.pgext.hibernate.PostgresqlExtensionsDialect ``` -If you just only add the dialect, hibernate will create a new sequence for every table to generate the sequential ids +If you just add the dialect, hibernate will create a new sequence for every table to generate the sequential ids used for the primary keys instead of a global sequence for all your tables. -If you're using Hibernate 4 you can also deactivate this behaviour and create only one unique sequence for all the tables with the following +You can also deactivate this behavior and create only one unique sequence for all the tables with the following property in your datasource definition: -```yaml -dataSource: - postgresql: - extensions: - sequence_per_table: false -} -``` - -For Hibernate 5 add the following to `grails-app/conf/application.groovy`: +Add the following to `grails-app/conf/application.groovy`: ```groovy grails.gorm.default.mapping = { @@ -182,14 +106,14 @@ The plugin supports the definition of `Integer`, `Long`, `Float`, `Double`, `Str classes. The `Enum` arrays behaves almost identical to `Integer` arrays in that they store and retrieve an array of ints. The -difference, however, is that this is used with an Array of Enums, rather than Ints. The Enums are serialized to their +difference, however, is that this is used with an Array of Enums, rather than ints. The Enums are serialized to their ordinal value before persisted to the database. On retrieval, they are then converted back into their original `Enum` type. #### Example ```groovy -import net.kaleidos.hibernate.usertype.ArrayType +import gpc.pgext.hibernate.usertype.ArrayType class Like { Integer[] favoriteNumbers = [] @@ -244,11 +168,11 @@ And now, with `psql`: 1 | {123,239,3498239,2344235} | {0.3,0.1} | {100.33,44.11} | {Spiderman,"Blade Runner",Starwars} | {5,17,9,6} | {0,2} ``` -#### Criterias +#### Criteria -The plugin also includes some hibernate criterias to use in your queries. Please check the -[services](https://github.com/kaleidos/grails-postgresql-extensions/tree/master/grails-app/services/test/criteria/array) -and the [tests](https://github.com/kaleidos/grails-postgresql-extensions/tree/master/src/integration-test/groovy/net/kaleidos/hibernate/array) +The plugin also includes some Hibernate criteria to use in your queries. Please check the +[services](https://github.com/gpc/grails-postgresql-extensions/tree/master/test-apps/app1/grails-app/services/app/criteria/array) +and the [tests](https://github.com/gpc/grails-postgresql-extensions/tree/master/test-apps/app1/src/integration-test/groovy/array) created to see all usage examples. You can also check the official [Postgresql Array operators](http://www.postgresql.org/docs/9.4/static/functions-array.html#ARRAY-OPERATORS-TABLE). @@ -729,16 +653,6 @@ It's important to note that the "raw" sql is appended to the criteria, so you ne if not you'll get a sql error during runtime. -## Authors - -You can send any questions to: - -- Iván López: lopez.ivan@gmail.com ([@ilopmar](https://twitter.com/ilopmar)) -- Alonso Torres: alonso.javier.torres@gmail.com ([@alotor](https://twitter.com/alotor)) - -Collaborations are appreciated :-) - - ## Release Notes Version | Date | Comments diff --git a/build.gradle b/build.gradle index 19ec900..299bdf4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,119 +1,24 @@ -buildscript { - ext { - grailsVersion = project.grailsVersion - gormVersion = project.gormVersion - } - repositories { - mavenLocal() - mavenCentral() - jcenter() - maven { url 'https://repo.grails.org/grails/core' } - } - dependencies { - classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "org.grails.plugins:hibernate5:7.0.0" - classpath 'net.saliman:gradle-cobertura-plugin:2.5.4' - classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.2' - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.0" - } -} - -version '7.0.0' -group 'org.grails.plugins' - -apply plugin: 'eclipse' -apply plugin: 'idea' -apply plugin: 'org.grails.grails-plugin' -apply plugin: 'org.grails.grails-plugin-publish' -apply plugin: 'cobertura' -apply plugin: 'com.github.kt3k.coveralls' -apply plugin: 'com.jfrog.bintray' - -ext { - gradleWrapperVersion = project.gradleWrapperVersion - grailsVersion = project.grailsVersion - gormVersion = project.gormVersion - hibernateVersion = project.hibernateVersion -} - -sourceCompatibility = 1.8 -targetCompatibility = 1.8 - -cobertura { - coverageExcludes = ['.*BootStrap.*', '.*test.*'] - coverageFormats = ['html', 'xml'] -} - -jar { - exclude 'test/**' - exclude 'UrlMappings.groovy' - exclude 'error.gsp' - exclude 'messages.properties' - exclude 'hibernate/**' - exclude 'layouts/**' - exclude 'spring/**' -} - -repositories { - mavenLocal() - mavenCentral() - jcenter() - maven { url 'https://repo.grails.org/grails/core' } -} - -dependencies { - // Grails deps - compile 'org.springframework.boot:spring-boot-starter-logging' - compile 'org.springframework.boot:spring-boot-autoconfigure' - compile 'org.grails:grails-core' - compile 'org.springframework.boot:spring-boot-starter-actuator' - compile 'org.springframework.boot:spring-boot-starter-tomcat' - compile 'org.grails:grails-dependencies' - compile 'org.grails:grails-web-boot' - console 'org.grails:grails-console' - - profile 'org.grails.profiles:web-plugin' - provided 'org.grails:grails-plugin-services' - provided 'org.grails:grails-plugin-domain-class' - testCompile 'org.grails:grails-gorm-testing-support' - - provided 'org.postgresql:postgresql:42.2.6' - - // plugins - provided 'org.grails.plugins:hibernate5' +// Workaround needed for nexus publishing bug +// version and group must be specified in the root project +// https://github.com/gradle-nexus/publish-plugin/issues/310 +version = projectVersion +group = 'this.will.be.overridden' - // libraries - provided "org.hibernate:hibernate-core:$hibernateVersion" - provided("org.hibernate:hibernate-ehcache:$hibernateVersion") { - exclude group: 'net.sf.ehcache', module: 'ehcache' - } - compile 'com.google.code.gson:gson:2.8.4' -} +subprojects { -bintray { - pkg { - userOrg = 'kaleidos' - name = 'postgresql-extensions' - issueTrackerUrl = 'https://github.com/kaleidosnet/grails-grails-postgresql-extensions/issues' - vcsUrl = 'https://github.com/kaleidosnet/grails-grails-postgresql-extensions/issues' + repositories { + mavenCentral() + maven { url = 'https://repo.grails.org/grails/restricted' } + maven { + url = 'https://repository.apache.org/content/groups/snapshots' + content { + includeVersionByRegex('org[.]apache[.](grails|groovy).*', '.*', '.*-SNAPSHOT') + } + } } -} - -grailsPublish { - user = System.getenv("BINTRAY_USER") ?: '' - key = System.getenv("BINTRAY_KEY") ?: '' - userOrg = 'kaleidos' - repo = 'plugins' - websiteUrl = 'https://github.com/kaleidos/grails-postgresql-extensions' - license { - name = 'Apache-2.0' + if (name == 'grails-postgresql-extensions') { + // This has to be applied here in the root project due to the nexus plugin requirements + apply plugin: 'org.apache.grails.gradle.grails-publish' } - issueTrackerUrl = 'https://github.com/kaleidosnet/grails-grails-postgresql-extensions/issues' - vcsUrl = 'https://github.com/kaleidos/grails-postgresql-extensions.git' - title = 'PostgreSQL Extensions' - desc = 'This is a grails plugin that provides hibernate user types to use Postgresql native types. It also provides new criterias to query this new native types.' - developers = [ivan: 'Iván López'] } - -apply from: "${rootProject.projectDir}/gradle/testVerbose.gradle" diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle new file mode 100644 index 0000000..56437fb --- /dev/null +++ b/buildSrc/build.gradle @@ -0,0 +1,24 @@ +plugins { + id 'groovy-gradle-plugin' +} + +def versions = new Properties() +file('../gradle.properties').withInputStream { + versions.load(it) +} + +repositories { + maven { url = 'https://repo.grails.org/grails/restricted' } + maven { + url = 'https://repository.apache.org/content/groups/snapshots' + content { + includeVersionByRegex('org[.]apache[.](grails|groovy).*', '.*', '.*-SNAPSHOT') + } + mavenContent { snapshotsOnly() } + } +} + +dependencies { + implementation platform("org.apache.grails:grails-bom:${versions['grailsVersion']}") + implementation 'org.apache.grails:grails-gradle-plugins' +} diff --git a/gradle.properties b/gradle.properties index bbc3fbc..5293811 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,14 @@ -gradleWrapperVersion=5.1.1 -grailsVersion=4.0.0 -hibernateVersion=5.4.0.Final -gormVersion=7.0.2.RELEASE +projectVersion=8.0.0-SNAPSHOT + +grailsVersion=7.0.0-RC2 +javaVersion=17 + +hibernate5Version=5.6.15.Final + +# This prevents the Grails Gradle Plugin from unnecessarily excluding slf4j-simple in the generated POMs +# https://github.com/grails/grails-gradle-plugin/issues/222 +slf4jPreventExclusion=true + +org.gradle.caching=true +org.gradle.daemon=true +org.gradle.parallel=true diff --git a/gradle/test-config.gradle b/gradle/test-config.gradle new file mode 100644 index 0000000..f31b098 --- /dev/null +++ b/gradle/test-config.gradle @@ -0,0 +1,39 @@ +dependencies { + add('testRuntimeOnly', 'org.junit.platform:junit-platform-launcher') +} + +tasks.withType(Test).configureEach { + + useJUnitPlatform() + + afterTest { desc, result -> + logger.quiet( + ' -- Executed test {} [{}] with result: {}', + desc.name, desc.className, result.resultType + ) + } + testLogging { + events('passed', 'skipped', 'failed') // 'standardOut' + showExceptions = true + exceptionFormat = 'full' + showCauses = true + showStackTraces = true + + // set options for log level DEBUG and INFO + debug { + events('passed', 'skipped', 'failed')//, 'started', 'standardOut', 'standardError' + exceptionFormat = 'full' + } + info.events = debug.events + info.exceptionFormat = debug.exceptionFormat + } + + afterSuite { desc, result -> + if (!desc.parent) { // will match the outermost suite + def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" + def startItem = '| ', endItem = ' |' + def repeatLength = startItem.length() + output.length() + endItem.length() + logger.quiet "\n${'-' * repeatLength}\n${startItem}${output}${endItem}\n${'-' * repeatLength}" + } + } +} \ No newline at end of file diff --git a/gradle/testVerbose.gradle b/gradle/testVerbose.gradle deleted file mode 100644 index a1149ee..0000000 --- a/gradle/testVerbose.gradle +++ /dev/null @@ -1,29 +0,0 @@ -tasks.withType(Test) { - afterTest { desc, result -> - //logger.quiet " -- Executed test ${desc.name} [${desc.className}] with result: ${result.resultType}" - } - testLogging { - events "passed", "skipped", "failed"//, "standardOut" - showExceptions true - exceptionFormat "full" - showCauses true - showStackTraces true - - // set options for log level DEBUG and INFO - debug { - events "passed", "skipped", "failed"//, "started", "standardOut", "standardError" - exceptionFormat "full" - } - info.events = debug.events - info.exceptionFormat = debug.exceptionFormat - - afterSuite { desc, result -> - if (!desc.parent) { // will match the outermost suite - def output = "Results: ${result.resultType} (${result.testCount} tests, ${result.successfulTestCount} successes, ${result.failedTestCount} failures, ${result.skippedTestCount} skipped)" - def startItem = '| ', endItem = ' |' - def repeatLength = startItem.length() + output.length() + endItem.length() - logger.quiet "\n${'-' * repeatLength}\n${startItem}${output}${endItem}\n${'-' * repeatLength}" - } - } - } -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 94336fc..1b33c55 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 558870d..d4081da 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d..23d15a9 100755 --- a/gradlew +++ b/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original 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 +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,92 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index e95643d..5eed7ee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,4 +1,22 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -9,25 +27,29 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -35,48 +57,36 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml deleted file mode 100644 index 9be0559..0000000 --- a/grails-app/conf/application.yml +++ /dev/null @@ -1,28 +0,0 @@ -grails: - profile: web-plugin - codegen: - defaultPackage: grails.postgresql.extensions -info: - app: - name: '@info.app.name@' - version: '@info.app.version@' - grailsVersion: '@info.app.grailsVersion@' -spring: - groovy: - template: - check-template-location: false - - ---- -dataSource: - pooled: true - jmxExport: true - driverClassName: org.postgresql.Driver - dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect - username: postgres_extensions - password: postgres_extensions - url: jdbc:postgresql://localhost/pg_extensions_test - dbCreate: create-drop - -hibernate: - dialect: net.kaleidos.hibernate.PostgresqlExtensionsDialect diff --git a/grails-app/conf/logback.groovy b/grails-app/conf/logback.groovy deleted file mode 100644 index 647d141..0000000 --- a/grails-app/conf/logback.groovy +++ /dev/null @@ -1,30 +0,0 @@ -import grails.util.BuildSettings -import grails.util.Environment - -// See http://logback.qos.ch/manual/groovy.html for details on configuration -appender('STDOUT', ConsoleAppender) { - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } -} - -def targetDir = BuildSettings.TARGET_DIR -if (Environment.isDevelopmentMode() && targetDir != null) { - appender("FULL_STACKTRACE", FileAppender) { - file = "${targetDir}/stacktrace.log" - append = true - encoder(PatternLayoutEncoder) { - pattern = "%level %logger - %msg%n" - } - } - logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false) - root(ERROR, ['STDOUT', 'FULL_STACKTRACE']) -} else { - root(ERROR, ['STDOUT']) -} - -logger('org.hibernate.SQL', DEBUG) - -logger('org.hibernate.type', TRACE) - -logger('org.hibernate.tool.hbm2ddl', DEBUG) diff --git a/grails-app/domain/test/array/TestDouble.groovy b/grails-app/domain/test/array/TestDouble.groovy deleted file mode 100644 index 841b25a..0000000 --- a/grails-app/domain/test/array/TestDouble.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.array - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType - -@ToString -class TestDouble { - - Double[] doubleNumbers - - static mapping = { - doubleNumbers type: ArrayType, params: [type: Double] - } - - static constraints = { - doubleNumbers nullable: true - } - -} diff --git a/grails-app/domain/test/array/TestFloat.groovy b/grails-app/domain/test/array/TestFloat.groovy deleted file mode 100644 index 3f5ef76..0000000 --- a/grails-app/domain/test/array/TestFloat.groovy +++ /dev/null @@ -1,20 +0,0 @@ -package test.array - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType - - -@ToString -class TestFloat { - - Float[] floatNumbers - - static mapping = { - floatNumbers type: ArrayType, params: [type: Float] - } - - static constraints = { - floatNumbers nullable: true - } - -} diff --git a/grails-app/domain/test/array/TestInteger.groovy b/grails-app/domain/test/array/TestInteger.groovy deleted file mode 100644 index 8237f24..0000000 --- a/grails-app/domain/test/array/TestInteger.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.array - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType - -@ToString -class TestInteger { - - Integer[] integerNumbers - - static mapping = { - integerNumbers type: ArrayType, params: ["type": Integer] - } - - static constraints = { - integerNumbers nullable: true - } - -} diff --git a/grails-app/domain/test/array/TestLong.groovy b/grails-app/domain/test/array/TestLong.groovy deleted file mode 100644 index a123e04..0000000 --- a/grails-app/domain/test/array/TestLong.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.array - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType - -@ToString -class TestLong { - - Long[] longNumbers - - static mapping = { - longNumbers type: ArrayType, params: [type: Long] - } - - static constraints = { - longNumbers nullable: true - } - -} diff --git a/grails-app/domain/test/array/TestString.groovy b/grails-app/domain/test/array/TestString.groovy deleted file mode 100644 index 0d84b7b..0000000 --- a/grails-app/domain/test/array/TestString.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.array - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType - -@ToString -class TestString { - - String[] stringArray - - static mapping = { - stringArray type: ArrayType, params: [type: String] - } - - static constraints = { - stringArray nullable: true - } - -} diff --git a/grails-app/domain/test/array/TestUuid.groovy b/grails-app/domain/test/array/TestUuid.groovy deleted file mode 100644 index bc02d1a..0000000 --- a/grails-app/domain/test/array/TestUuid.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.array - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType - -@ToString -class TestUuid { - - UUID[] uuidArray - - static mapping = { - uuidArray type: ArrayType, params: [type: UUID] - } - - static constraints = { - uuidArray nullable: true - } - -} diff --git a/grails-app/domain/test/criteria/array/User.groovy b/grails-app/domain/test/criteria/array/User.groovy deleted file mode 100644 index 3144234..0000000 --- a/grails-app/domain/test/criteria/array/User.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package test.criteria.array - -class User { - - String name - Like like - - static mapping = { - table "pg_extensions_user" - } - - String toString() { - name - } - -} diff --git a/grails-app/domain/test/hstore/TestHstoreMap.groovy b/grails-app/domain/test/hstore/TestHstoreMap.groovy deleted file mode 100644 index 66890c3..0000000 --- a/grails-app/domain/test/hstore/TestHstoreMap.groovy +++ /dev/null @@ -1,25 +0,0 @@ -package test.hstore - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.HstoreMapType - -@ToString -class TestHstoreMap { - - String name - Integer luckyNumber - - Map testAttributes - - static constraints = { - name nullable: true - luckyNumber nullable: true - } - - static mapping = { - testAttributes type: HstoreMapType - } - -} - - diff --git a/grails-app/domain/test/json/TestMapJson.groovy b/grails-app/domain/test/json/TestMapJson.groovy deleted file mode 100644 index 2028fb8..0000000 --- a/grails-app/domain/test/json/TestMapJson.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package test.json - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.JsonMapType - -@ToString -class TestMapJson { - - Map data - - static constraints = { - data nullable: true - } - - static mapping = { - data type: JsonMapType - } -} \ No newline at end of file diff --git a/grails-app/domain/test/json/TestMapJsonb.groovy b/grails-app/domain/test/json/TestMapJsonb.groovy deleted file mode 100644 index aadcef3..0000000 --- a/grails-app/domain/test/json/TestMapJsonb.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.json - -import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.JsonbMapType - -@ToString -class TestMapJsonb { - - Map data - - static constraints = { - data nullable: true - } - - static mapping = { - data type: JsonbMapType - } - -} \ No newline at end of file diff --git a/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy b/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy deleted file mode 100644 index e850fe5..0000000 --- a/grails-app/services/test/criteria/array/PgArrayTestSearchService.groovy +++ /dev/null @@ -1,58 +0,0 @@ -package test.criteria.array - -class PgArrayTestSearchService { - - static transactional = false - - List search(String field, String criteriaName, value) { - Like.withCriteria { - "${criteriaName}" field, value - } - } - - List search(String field, String criteriaName) { - Like.withCriteria { - "${criteriaName}" field - } - } - - List searchWithJoin(String field, String criteriaName, value) { - User.withCriteria { - like { - "${criteriaName}" field, value - } - } - } - - List searchWithJoin(String field, String criteriaName) { - User.withCriteria { - like { - "${criteriaName}" field - } - } - } - - List searchWithJoinByStringOrInteger(Map params, String criteriaName) { - User.withCriteria { - like { - or { - params.each { entry-> - "${criteriaName}" (entry.key, entry.value) - } - } - } - } - } - - List searchWithJoinAnd(Map params, String criteriaName) { - User.withCriteria { - like { - and { - params.each { entry-> - "${criteriaName}" (entry.key, entry.value) - } - } - } - } - } -} diff --git a/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy b/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy deleted file mode 100644 index 8c7676d..0000000 --- a/grails-app/services/test/criteria/hstore/PgHstoreTestSearchService.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package test.criteria.hstore - -import test.hstore.TestHstoreMap - -class PgHstoreTestSearchService { - static transactional = false - - List search(String field, String criteriaName, value) { - TestHstoreMap.withCriteria { - "${criteriaName}" field, value - } - } -} diff --git a/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy b/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy deleted file mode 100644 index f2f5b2a..0000000 --- a/grails-app/services/test/criteria/json/PgJsonTestSearchService.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package test.criteria.json - -import test.json.TestMapJson - -class PgJsonTestSearchService { - static transactional = false - - List search(String criteriaName, String field, String jsonAttribute, value) { - TestMapJson.withCriteria { - "${criteriaName}" field, jsonAttribute, value.toString() - } - } - - List search(String criteriaName, String field, String jsonOp, String jsonAttribute, String sqlOp, value) { - TestMapJson.withCriteria { - "${criteriaName}" field, jsonOp, jsonAttribute, sqlOp, value.toString() - } - } -} diff --git a/grails-app/services/test/criteria/json/PgJsonbTestSearchService.groovy b/grails-app/services/test/criteria/json/PgJsonbTestSearchService.groovy deleted file mode 100644 index 34e8f66..0000000 --- a/grails-app/services/test/criteria/json/PgJsonbTestSearchService.groovy +++ /dev/null @@ -1,25 +0,0 @@ -package test.criteria.json - -import test.json.TestMapJsonb - -class PgJsonbTestSearchService { - static transactional = false - - List search(String criteriaName, String field, value) { - TestMapJsonb.withCriteria { - "${criteriaName}" field, value - } - } - - List search(String criteriaName, String field, String jsonAttribute, value) { - TestMapJsonb.withCriteria { - "${criteriaName}" field, jsonAttribute, value.toString() - } - } - - List search(String criteriaName, String field, String jsonOp, String jsonAttribute, String sqlOp, value) { - TestMapJsonb.withCriteria { - "${criteriaName}" field, jsonOp, jsonAttribute, sqlOp, value.toString() - } - } -} diff --git a/grails-app/services/test/order/PgOrderService.groovy b/grails-app/services/test/order/PgOrderService.groovy deleted file mode 100644 index 3108958..0000000 --- a/grails-app/services/test/order/PgOrderService.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package test.order - -import static net.kaleidos.hibernate.order.OrderByRandom.byRandom -import static net.kaleidos.hibernate.order.OrderBySqlFormula.sqlFormula - -import test.json.TestMapJsonb - -class PgOrderService { - - List orderByJson() { - return TestMapJsonb.withCriteria { - order sqlFormula("(data->'name') desc") - } - } - - List orderByRandom() { - return TestMapJsonb.withCriteria { - order byRandom() - } - } -} diff --git a/plugin/build.gradle b/plugin/build.gradle new file mode 100644 index 0000000..de5f5d3 --- /dev/null +++ b/plugin/build.gradle @@ -0,0 +1,76 @@ +plugins { + id 'java-library' + id 'org.apache.grails.gradle.grails-plugin' +} + +version = projectVersion +group = 'io.github.gpc' + +grailsPublish { + artifactId = 'grails-postgresql-extensions' + githubSlug = 'gpc/grails-postgresql-extensions' + license.name = 'Apache-2.0' + title = 'Grails PostgreSQL Extensions Plugin' + desc = 'A Grails plugin that adds Hibernate UserTypes for PostgreSQL native types, ' + + 'like Array, HStore, JSON, JSONB, ..., and GORM criteria extensions to query them.' + developers = [ + ilopmar: 'Iván López', + alotor: 'Alonso Torres', + mattfeury: 'Matt Feury', + alvarosanchez: 'Alvaro Sanchez-Mariscal', + aeischeid: 'Aaron Eischeid', + mkobel: 'Moritz Kobel', + manuelvio: 'Manuel Unno Vio', + bameda: 'David Barragán Merino', + nobeans: 'Yasuharu Nakano', + burtbeckwith: 'Burt Beckwith', + timic: 'Timur Salyakhutdinov', + zlegein: 'Zach Legein', + tmarthal: 'Tom Marthaler', + pabloalba: 'Pablo Alba', + cornercase: 'Eamon Doyle', + poundex: 'Adam Pounder', + gregopet: 'Gregor Petrin', + unknown: 'Tom Potts', + sabst: 'Sabst', + donbeave: 'Alexey Zhokov', + jglapa: 'Jakub Glapa', + jamesdh: 'James Hardwick', + butters16: 'John Keith', + erichelgeson: 'Eric Helgeson', + albertop19: 'albertop19', + gtors: 'Andrey T', + matrei: 'Mattias Reichel', + ] +} + +dependencies { + + implementation platform("org.apache.grails:grails-bom:$grailsVersion") + + compileOnly 'org.apache.grails:grails-core', { // Provided + // impl: Plugin + } + compileOnly 'org.apache.grails:grails-data-hibernate5', { + // Must be provided by the Grails application + } + compileOnly 'org.springframework:spring-core', { // Provided + // impl: Assert + } + + implementation 'com.google.code.gson:gson' + implementation "org.hibernate:hibernate-core-jakarta:$hibernate5Version" + implementation 'org.postgresql:postgresql' + + testImplementation 'org.spockframework:spock-core' + + testRuntimeOnly 'org.springframework:spring-core', { + // Assert + } +} + +compileJava.options.release = javaVersion.toInteger() + +apply { + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') +} \ No newline at end of file diff --git a/plugin/src/main/groovy/gpc/pgext/GrailsPostgresqlExtensionsGrailsPlugin.groovy b/plugin/src/main/groovy/gpc/pgext/GrailsPostgresqlExtensionsGrailsPlugin.groovy new file mode 100644 index 0000000..b578b83 --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/GrailsPostgresqlExtensionsGrailsPlugin.groovy @@ -0,0 +1,57 @@ +package gpc.pgext + +import groovy.transform.CompileStatic + +import grails.plugins.Plugin + +@CompileStatic +class GrailsPostgresqlExtensionsGrailsPlugin extends Plugin { + + def grailsVersion = '7.0.0-SNAPSHOT > *' + def title = 'Grails PostgreSQL Extensions Plugin' + def author = 'Iván López' + def description = 'Provides Hibernate user types supporting PostgreSQL Native Types ' + + 'like Array, HStore, JSON, JSONB,... as well as new criteria to query ' + + 'these native types.' + def documentation = 'https://github.com/gpc/grails-postgresql-extensions' + def license = 'APACHE' + def organization = [ + name: 'GPC', + url: 'https://github.com/gpc' + ] + def developers = [ + [name: 'Alonso Torres'], + [name: 'Matt Feury'], + [name: 'Alvaro Sanchez-Mariscal'], + [name: 'Aaron Eischeid'], + [name: 'Moritz Kobel'], + [name: 'Manuel Unno Vio'], + [name: 'David Barragán Merino'], + [name: 'Yasuharu Nakano'], + [name: 'Burt Beckwith'], + [name: 'Timur Salyakhutdinov'], + [name: 'Zach Legein'], + [name: 'Tom Marthaler'], + [name: 'Pablo Alba'], + [name: 'Eamon Doyle'], + [name: 'Adam Pounder'], + [name: 'Gregor Petrin'], + [name: 'Tom Potts'], + [name: 'Sabst'], + [name: 'Alexey Zhokov'], + [name: 'Jakub Glapa'], + [name: 'James Hardwick'], + [name: 'John Keith'], + [name: 'Eric Helgeson'], + [name: 'albertop19'], + [name: 'Andrey T'], + [name: 'Mattias Reichel'], + ] + def issueManagement = [ + system: 'GITHUB', + url: 'https://github.com/gpc/grails-postgresql-extensions/issues' + ] + def scm = [ + url: 'https://github.com/gpc/grails-postgresql-extensions' + ] +} diff --git a/src/main/groovy/net/kaleidos/hibernate/PostgresqlExtensionsDialect.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/PostgresqlExtensionsDialect.groovy similarity index 81% rename from src/main/groovy/net/kaleidos/hibernate/PostgresqlExtensionsDialect.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/PostgresqlExtensionsDialect.groovy index 0edb9d3..f5d8a50 100644 --- a/src/main/groovy/net/kaleidos/hibernate/PostgresqlExtensionsDialect.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/PostgresqlExtensionsDialect.groovy @@ -1,13 +1,15 @@ -package net.kaleidos.hibernate +package gpc.pgext.hibernate + +import java.sql.Types import groovy.transform.CompileStatic -import net.kaleidos.hibernate.usertype.ArrayType -import net.kaleidos.hibernate.usertype.HstoreMapType -import net.kaleidos.hibernate.usertype.JsonMapType -import net.kaleidos.hibernate.usertype.JsonbMapType + import org.hibernate.dialect.PostgreSQL95Dialect -import java.sql.Types +import gpc.pgext.hibernate.usertype.ArrayType +import gpc.pgext.hibernate.usertype.HstoreMapType +import gpc.pgext.hibernate.usertype.JsonMapType +import gpc.pgext.hibernate.usertype.JsonbMapType @CompileStatic class PostgresqlExtensionsDialect extends PostgreSQL95Dialect { diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/array/PgArrayExpression.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgArrayExpression.groovy similarity index 50% rename from src/main/groovy/net/kaleidos/hibernate/criterion/array/PgArrayExpression.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgArrayExpression.groovy index 2bf1046..f2a1832 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/array/PgArrayExpression.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgArrayExpression.groovy @@ -1,16 +1,16 @@ -package net.kaleidos.hibernate.criterion.array +package gpc.pgext.hibernate.criterion.array import groovy.transform.CompileStatic -import net.kaleidos.hibernate.usertype.ArrayType -import net.kaleidos.hibernate.utils.PgArrayUtils + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue import org.hibernate.type.CustomType -import org.hibernate.type.Type + +import gpc.pgext.hibernate.usertype.ArrayType +import gpc.pgext.hibernate.utils.PgArrayUtils @CompileStatic class PgArrayExpression implements Criterion { @@ -21,7 +21,7 @@ class PgArrayExpression implements Criterion { private final Object value private final String op - protected PgArrayExpression(String propertyName, Object value, String op) { + PgArrayExpression(String propertyName, Object value, String op) { this.propertyName = propertyName this.value = value this.op = op @@ -29,47 +29,37 @@ class PgArrayExpression implements Criterion { @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - ArrayType arrayType = checkAndGetArrayType(criteria, criteriaQuery) - - String postgresArrayType = PgArrayUtils.getNativeSqlType(arrayType.getTypeClass()) + "[]" - - return StringHelper.join( - " and ", - StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), " ${op} CAST(? as ${postgresArrayType})") - ) + def arrayType = checkAndGetArrayType(criteria, criteriaQuery) + def postgresArrayType = PgArrayUtils.getNativeSqlType(arrayType.getTypeClass()) + '[]' + criteriaQuery.findColumns(propertyName, criteria) + .collect {"$it $op CAST(? as $postgresArrayType)" } + .join(' and ') } @Override TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - ArrayType arrayType = checkAndGetArrayType(criteria, criteriaQuery) - - Object[] arrValue - if (arrayType.typeClass.isEnum()) { - arrValue = PgArrayUtils.getValueAsArrayOfType(value, Integer, mapValueToEnumOrdinal()) - } else { - arrValue = PgArrayUtils.getValueAsArrayOfType(value, arrayType.typeClass) - } - - return criteriaQuery.getTypedValue(criteria, propertyName, arrValue) as TypedValue[] + def arrayType = checkAndGetArrayType(criteria, criteriaQuery) + def arrValue = arrayType.typeClass.isEnum() ? + PgArrayUtils.getValueAsArrayOfType(value, Integer, mapValueToEnumOrdinal()) : + PgArrayUtils.getValueAsArrayOfType(value, arrayType.typeClass) + criteriaQuery.getTypedValue(criteria, propertyName, arrValue) as TypedValue[] } private PgArrayUtils.MapFunction mapValueToEnumOrdinal() { - { Object o -> + return { Object o -> try { return (o as Enum).ordinal() } catch (ClassCastException e) { - throw new HibernateException("Unable to cast object ${o} to Enum", e) + throw new HibernateException("Unable to cast object $o to Enum", e) } } as PgArrayUtils.MapFunction } private ArrayType checkAndGetArrayType(Criteria criteria, CriteriaQuery criteriaQuery) { - Type propertyType = criteriaQuery.getType(criteria, propertyName) - + def propertyType = criteriaQuery.getType(criteria, propertyName) if (!(propertyType instanceof CustomType) || !((propertyType as CustomType).userType instanceof ArrayType)) { - throw new HibernateException("Property is not an instance of the postgres type ArrayType. Type is: ${propertyType.class}") + throw new HibernateException("Property is not an instance of the postgres type ArrayType. Type is: $propertyType.class") } - - return (propertyType as CustomType).getUserType() as ArrayType + (propertyType as CustomType).userType as ArrayType } } diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/array/PgArrayILikeFunction.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgArrayILikeFunction.groovy similarity index 66% rename from src/main/groovy/net/kaleidos/hibernate/criterion/array/PgArrayILikeFunction.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgArrayILikeFunction.groovy index dbc4dc8..b680031 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/array/PgArrayILikeFunction.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgArrayILikeFunction.groovy @@ -1,9 +1,9 @@ -package net.kaleidos.hibernate.criterion.array +package gpc.pgext.hibernate.criterion.array import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue @@ -17,18 +17,16 @@ class PgArrayILikeFunction implements Criterion { private final String propertyName private final String value - protected PgArrayILikeFunction(String propertyName, String value) { + PgArrayILikeFunction(String propertyName, String value) { this.propertyName = propertyName this.value = value } @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), "") - for (int i = 0; i < columns.length; i++) { - columns[i] = "text(${columns[i]}) ilike ?" - } - return StringHelper.join(" and ", columns) + criteriaQuery.findColumns(propertyName, criteria) + .collect { "text($it) ilike ?" } + .join(' and ') } @Override diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/array/PgEmptinessExpression.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgEmptinessExpression.groovy similarity index 71% rename from src/main/groovy/net/kaleidos/hibernate/criterion/array/PgEmptinessExpression.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgEmptinessExpression.groovy index b62c481..62a7de3 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/array/PgEmptinessExpression.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/array/PgEmptinessExpression.groovy @@ -1,9 +1,9 @@ -package net.kaleidos.hibernate.criterion.array +package gpc.pgext.hibernate.criterion.array import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue @@ -18,17 +18,16 @@ class PgEmptinessExpression implements Criterion { private static final TypedValue[] NO_VALUES = new TypedValue[0] - protected PgEmptinessExpression(String propertyName, String op) { + PgEmptinessExpression(String propertyName, String op) { this.propertyName = propertyName this.op = op } @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - StringHelper.join( - " and ", - StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), " ${op} '{}'") - ) + criteriaQuery.findColumns(propertyName, criteria) + .collect { "$it $op '{}'" } + .join(' and ') } @Override diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreILikeValueFunction.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreILikeValueFunction.groovy new file mode 100644 index 0000000..24e9ea0 --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreILikeValueFunction.groovy @@ -0,0 +1,22 @@ +package gpc.pgext.hibernate.criterion.hstore + +import groovy.transform.CompileStatic + +import org.hibernate.Criteria +import org.hibernate.HibernateException +import org.hibernate.criterion.CriteriaQuery + +@CompileStatic +class PgHstoreILikeValueFunction extends PgHstoreValueFunction { + + PgHstoreILikeValueFunction(String propertyName, Object value) { + super(propertyName, value, '') + } + + @Override + String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { + criteriaQuery.findColumns(propertyName, criteria) + .collect { "text(avals($it)) ilike ?" } + .join(' and ') + } +} diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreOperatorExpression.groovy similarity index 62% rename from src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreOperatorExpression.groovy index 9be43e9..19e4fef 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreOperatorExpression.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreOperatorExpression.groovy @@ -1,16 +1,18 @@ -package net.kaleidos.hibernate.criterion.hstore +package gpc.pgext.hibernate.criterion.hstore import groovy.transform.CompileStatic -import net.kaleidos.hibernate.usertype.HstoreHelper + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue +import gpc.pgext.hibernate.usertype.HstoreHelper + @CompileStatic class PgHstoreOperatorExpression implements Criterion { + private static final long serialVersionUID = 2872183637309166619L private final String propertyName @@ -18,7 +20,11 @@ class PgHstoreOperatorExpression implements Criterion { private final String operator private static final TypedValue[] NO_VALUES = new TypedValue[0] - protected PgHstoreOperatorExpression(String propertyName, Map value, String operator) { + PgHstoreOperatorExpression(String propertyName, Object value, String operator) { + this(propertyName, value as Map, operator) + } + + PgHstoreOperatorExpression(String propertyName, Map value, String operator) { this.propertyName = propertyName this.value = value this.operator = operator @@ -26,11 +32,9 @@ class PgHstoreOperatorExpression implements Criterion { @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), "") - for (int i = 0; i < columns.length; i++) { - columns[i] = "${columns[i]} ${operator} '${HstoreHelper.toString(value)}'" - } - return StringHelper.join(" and ", columns) + criteriaQuery.findColumns(propertyName, criteria) + .collect { "$it $operator '${HstoreHelper.toString(value)}'" } + .join(' and ') } @Override diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreValueFunction.groovy similarity index 66% rename from src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreValueFunction.groovy index d384d0c..8174d37 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreValueFunction.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/hstore/PgHstoreValueFunction.groovy @@ -1,9 +1,9 @@ -package net.kaleidos.hibernate.criterion.hstore +package gpc.pgext.hibernate.criterion.hstore import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue @@ -11,13 +11,14 @@ import org.hibernate.type.StringType @CompileStatic class PgHstoreValueFunction implements Criterion { + private static final long serialVersionUID = 2872183637309166619L protected final String propertyName protected final Object value protected final String function - protected PgHstoreValueFunction(String propertyName, Object value, String function) { + PgHstoreValueFunction(String propertyName, Object value, String function) { this.propertyName = propertyName this.value = value this.function = function @@ -25,11 +26,9 @@ class PgHstoreValueFunction implements Criterion { @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), "") - for (int i = 0; i < columns.length; i++) { - columns[i] = "${function}(${columns[i]}, ?)" - } - return StringHelper.join(" and ", columns) + criteriaQuery.findColumns(propertyName, criteria) + .collect { "$function($it, ?)" } + .join(' and ') } @Override diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/json/PgJsonExpression.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/json/PgJsonExpression.groovy similarity index 73% rename from src/main/groovy/net/kaleidos/hibernate/criterion/json/PgJsonExpression.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/json/PgJsonExpression.groovy index 0ef62f3..e050557 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/json/PgJsonExpression.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/json/PgJsonExpression.groovy @@ -1,9 +1,9 @@ -package net.kaleidos.hibernate.criterion.json +package gpc.pgext.hibernate.criterion.json import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue @@ -20,7 +20,7 @@ class PgJsonExpression implements Criterion { private final String sqlOp private final Object value - protected PgJsonExpression(String propertyName, String jsonOp, String jsonAttribute, String sqlOp, Object value) { + PgJsonExpression(String propertyName, String jsonOp, String jsonAttribute, String sqlOp, Object value) { this.propertyName = propertyName this.jsonOp = jsonOp this.jsonAttribute = jsonAttribute @@ -30,10 +30,9 @@ class PgJsonExpression implements Criterion { @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return StringHelper.join( - " and ", - StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), jsonOp + "'" + jsonAttribute + "' " + sqlOp + " ?") - ) + criteriaQuery.findColumns(propertyName, criteria) + .collect { "$it$jsonOp'$jsonAttribute' $sqlOp ?" } + .join(' and ') } @Override diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/json/PgJsonbOperator.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/json/PgJsonbOperator.groovy similarity index 72% rename from src/main/groovy/net/kaleidos/hibernate/criterion/json/PgJsonbOperator.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/criterion/json/PgJsonbOperator.groovy index a30b5ff..425e980 100644 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/json/PgJsonbOperator.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/criterion/json/PgJsonbOperator.groovy @@ -1,9 +1,9 @@ -package net.kaleidos.hibernate.criterion.json +package gpc.pgext.hibernate.criterion.json import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper import org.hibernate.criterion.CriteriaQuery import org.hibernate.criterion.Criterion import org.hibernate.engine.spi.TypedValue @@ -17,7 +17,7 @@ class PgJsonbOperator implements Criterion { private final Object value private final String op - protected PgJsonbOperator(String propertyName, Object value, String op) { + PgJsonbOperator(String propertyName, Object value, String op) { this.propertyName = propertyName this.value = value this.op = op @@ -25,10 +25,9 @@ class PgJsonbOperator implements Criterion { @Override String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return StringHelper.join( - " and ", - StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), " ${op} ?") - ) + criteriaQuery.findColumns(propertyName, criteria) + .collect { "$it $op ?" } + .join(' and ') } @Override diff --git a/src/main/groovy/net/kaleidos/hibernate/order/OrderByRandom.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/order/OrderByRandom.groovy similarity index 94% rename from src/main/groovy/net/kaleidos/hibernate/order/OrderByRandom.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/order/OrderByRandom.groovy index 1d3edb2..02ed0f4 100644 --- a/src/main/groovy/net/kaleidos/hibernate/order/OrderByRandom.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/order/OrderByRandom.groovy @@ -1,6 +1,7 @@ -package net.kaleidos.hibernate.order +package gpc.pgext.hibernate.order import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException import org.hibernate.criterion.CriteriaQuery diff --git a/src/main/groovy/net/kaleidos/hibernate/order/OrderBySqlFormula.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/order/OrderBySqlFormula.groovy similarity index 88% rename from src/main/groovy/net/kaleidos/hibernate/order/OrderBySqlFormula.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/order/OrderBySqlFormula.groovy index b40fc35..ba80391 100644 --- a/src/main/groovy/net/kaleidos/hibernate/order/OrderBySqlFormula.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/order/OrderBySqlFormula.groovy @@ -1,6 +1,7 @@ -package net.kaleidos.hibernate.order +package gpc.pgext.hibernate.order import groovy.transform.CompileStatic + import org.hibernate.Criteria import org.hibernate.HibernateException import org.hibernate.criterion.CriteriaQuery @@ -8,13 +9,15 @@ import org.hibernate.criterion.Order /** * Extends {@link org.hibernate.criterion.Order} to allow ordering by an SQL formula passed by the user. - * Is simply appends the sqlFormula passed by the user to the resulting SQL query, without any verification. + * It simply appends the sqlFormula passed by the user to the resulting SQL query, + * without any verification. * * From: http://blog.tremend.ro/2008/06/10/how-to-order-by-a-custom-sql-formulaexpression-when-using-hibernate-criteria-api/ * */ @CompileStatic class OrderBySqlFormula extends Order { + private String sqlFormula /** diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/ArrayCriterias.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/ArrayCriterias.groovy new file mode 100644 index 0000000..f3fa5b9 --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/ArrayCriterias.groovy @@ -0,0 +1,150 @@ +package gpc.pgext.hibernate.postgresql.criteria + +import groovy.transform.CompileStatic + +import org.hibernate.criterion.Criterion + +import grails.orm.HibernateCriteriaBuilder + +import gpc.pgext.hibernate.criterion.array.PgArrayExpression +import gpc.pgext.hibernate.criterion.array.PgArrayILikeFunction +import gpc.pgext.hibernate.criterion.array.PgEmptinessExpression + +import static gpc.pgext.hibernate.utils.CriteriaUtils.addToCriteria +import static gpc.pgext.hibernate.utils.CriteriaUtils.calculatePropertyName +import static gpc.pgext.hibernate.utils.CriteriaUtils.calculatePropertyValue +import static gpc.pgext.hibernate.utils.CriteriaUtils.throwRuntimeException +import static gpc.pgext.hibernate.utils.CriteriaUtils.validateExpression +import static gpc.pgext.hibernate.utils.CriteriaUtils.validateSimpleExpression + +@CompileStatic +class ArrayCriterias { + + /** + * Creates a "contains in native array" Criterion based on the specified property name and value + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayContains(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgArrayContains', PgArrayExpression, propertyName, propertyValue, '@>') + } + + /** + * Creates a "is contained by in native array" Criterion based on the specified property name and value + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayIsContainedBy(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgArrayIsContainedBy', PgArrayExpression, propertyName, propertyValue, '<@') + } + + /** + * Creates a "overlap in native array" Criterion based on the specified property name and value + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayOverlaps(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgArrayOverlaps', PgArrayExpression, propertyName, propertyValue, '&&') + } + + /** + * Creates an "is empty array" Criterion based on the specified property name + * @param propertyName The property name + * @return A Criterion instance + */ + static Criterion pgArrayIsEmpty(HibernateCriteriaBuilder self, String propertyName) { + if (!validateSimpleExpression(self)) { + throwRuntimeException( + self, + "Call to [pgArrayIsEmpty] with propertyName [$propertyName] not allowed here." + ) + } + addToCriteria( + self, + new PgEmptinessExpression( + calculatePropertyName(self, propertyName), + '=' + ) + ) + } + + /** + * Creates an "is not empty array" Criterion based on the specified property name + * @param propertyName The property name + * @return A Criterion instance + */ + static Criterion pgArrayIsNotEmpty(HibernateCriteriaBuilder self, String propertyName) { + if (!validateSimpleExpression(self)) { + throwRuntimeException( + self, + "Call to [pgArrayIsNotEmpty] with propertyName [$propertyName] not allowed here." + ) + } + addToCriteria( + self, + new PgEmptinessExpression( + calculatePropertyName(self, propertyName), + '<>' + ) + ) + } + + /** + * Creates a "contains in native array" or "is empty native array" Criterion based on the specified property name and value + * If the propertyValue is empty, the 'contains' operator is used and if the propertyValue is not empty, the 'isEmpty' + * operator is used. + * + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayIsEmptyOrContains(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + validateExpression(self, 'pgArrayIsEmptyOrContains', propertyName, propertyValue) + def name = calculatePropertyName(self, propertyName) + def value = calculatePropertyValue(self, propertyValue) + value ? + addToCriteria(self, new PgArrayExpression(name, value, '@>')) : + addToCriteria(self, new PgEmptinessExpression(name, '=')) + } + + /** + * Creates a "equals in native array" Criterion based on the specified property name and value + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayEquals(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgArrayEquals', PgArrayExpression, propertyName, propertyValue, '=') + } + + + /** + * Creates a "not equals in native array" Criterion based on the specified property name and value + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayNotEquals(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgArrayNotEquals', PgArrayExpression, propertyName, propertyValue, '<>') + } + + /** + * Creates a "ilike in native array" Criterion based on the specified property name and value + * @param propertyName The property name + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgArrayILike(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + validateExpression(self, 'pgArrayLike', propertyName, propertyValue) + addToCriteria( + self, + new PgArrayILikeFunction( + calculatePropertyName(self, propertyName), + calculatePropertyValue(self, propertyValue) as String + ) + ) + } +} diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/HstoreCriterias.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/HstoreCriterias.groovy new file mode 100644 index 0000000..f6b7304 --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/HstoreCriterias.groovy @@ -0,0 +1,33 @@ +package gpc.pgext.hibernate.postgresql.criteria + +import groovy.transform.CompileStatic + +import org.hibernate.criterion.Criterion + +import grails.orm.HibernateCriteriaBuilder + +import gpc.pgext.hibernate.criterion.hstore.PgHstoreILikeValueFunction +import gpc.pgext.hibernate.criterion.hstore.PgHstoreOperatorExpression +import gpc.pgext.hibernate.criterion.hstore.PgHstoreValueFunction + +import static gpc.pgext.hibernate.utils.CriteriaUtils.addToCriteria + +@CompileStatic +class HstoreCriterias { + + static Criterion pgHstoreContainsKey(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgHstoreContainsKey', PgHstoreValueFunction, propertyName, propertyValue, 'exist') + } + + static Criterion pgHstoreContains(HibernateCriteriaBuilder self, String propertyName, Map values) { + addToCriteria(self, 'pgHstoreContains', PgHstoreOperatorExpression, propertyName, values, '@>') + } + + static Criterion pgHstoreIsContained(HibernateCriteriaBuilder self, String propertyName, Map values) { + addToCriteria(self, 'pgHstoreIsContained', PgHstoreOperatorExpression, propertyName, values, '<@') + } + + static Criterion pgHstoreILikeValue(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgHstoreILikeValue', PgHstoreILikeValueFunction, propertyName, propertyValue) + } +} diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/JsonCriterias.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/JsonCriterias.groovy new file mode 100644 index 0000000..ef79003 --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/postgresql/criteria/JsonCriterias.groovy @@ -0,0 +1,94 @@ +package gpc.pgext.hibernate.postgresql.criteria + +import groovy.transform.CompileStatic + +import org.hibernate.criterion.Criterion + +import grails.orm.HibernateCriteriaBuilder + +import gpc.pgext.hibernate.criterion.json.PgJsonExpression +import gpc.pgext.hibernate.criterion.json.PgJsonbOperator + +import static gpc.pgext.hibernate.utils.CriteriaUtils.addToCriteria +import static gpc.pgext.hibernate.utils.CriteriaUtils.calculatePropertyName +import static gpc.pgext.hibernate.utils.CriteriaUtils.calculatePropertyValue +import static gpc.pgext.hibernate.utils.CriteriaUtils.throwRuntimeException +import static gpc.pgext.hibernate.utils.CriteriaUtils.validateSimpleExpression + +@CompileStatic +class JsonCriterias { + + /** + * Creates a "json has field value" Criterion based on the specified property name and value + * @param propertyName The property name (json field) + * @param jsonAttribute The json attribute + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgJsonHasFieldValue(HibernateCriteriaBuilder self, String propertyName, String jsonAttribute, Object propertyValue) { + if (!validateSimpleExpression(self)) { + throwRuntimeException( + self, + "Call to [pgJsonHasFieldValue] with propertyName [$propertyName], jsonAttribute [$jsonAttribute] and value [$propertyValue] is not allowed here." + ) + } + addToCriteria( + self, + new PgJsonExpression( + calculatePropertyName(self, propertyName), + '->>', + jsonAttribute, + '=', + calculatePropertyValue(self, propertyValue) as String + ) + ) + } + + /** + * Creates a "json contains another json" Criterion based on the specified property name and value + * @param propertyName The property name (jsonb field) + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgJsonbContains(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgJsonbContains', PgJsonbOperator, propertyName, propertyValue, '@>') + } + + /** + * Creates a "json is contained in another json" Criterion based on the specified property name and value + * @param propertyName The property name (jsonb field) + * @param propertyValue The property value + * @return A Criterion instance + */ + static Criterion pgJsonbIsContained(HibernateCriteriaBuilder self, String propertyName, Object propertyValue) { + addToCriteria(self, 'pgJsonbIsContained', PgJsonbOperator, propertyName, propertyValue, '<@') + } + + /** + * Creates a "json on field value" Criterion based on the specified property name and value + * @param propertyName The property name (json field) + * @param jsonAttribute The json attribute + * @param jsonOp The json operator (->>, #>, ...) + * @param propertyValue The property value + * @param sqlOp The sql operator (=, <>, ilike, ...) + * @return A Criterion instance + */ + static Criterion pgJson(HibernateCriteriaBuilder self, String propertyName, String jsonOp, String jsonAttribute, String sqlOp, Object propertyValue) { + if (!validateSimpleExpression(self)) { + throwRuntimeException( + self, + "Call to [pgJson] with propertyName [$propertyName], json operator [$jsonOp], jsonAttribute [$jsonAttribute], sql operator [$sqlOp] and value [$propertyValue] is not allowed here." + ) + } + addToCriteria( + self, + new PgJsonExpression( + calculatePropertyName(self, propertyName), + jsonOp, + jsonAttribute, + sqlOp, + calculatePropertyValue(self, propertyValue) as String + ) + ) + } +} diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/ArrayType.java b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/ArrayType.java similarity index 93% rename from src/main/groovy/net/kaleidos/hibernate/usertype/ArrayType.java rename to plugin/src/main/groovy/gpc/pgext/hibernate/usertype/ArrayType.java index 67f2a2f..7d0c7e8 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/ArrayType.java +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/ArrayType.java @@ -1,10 +1,4 @@ -package net.kaleidos.hibernate.usertype; - -import net.kaleidos.hibernate.utils.PgArrayUtils; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.usertype.ParameterizedType; -import org.hibernate.usertype.UserType; +package gpc.pgext.hibernate.usertype; import java.io.Serializable; import java.sql.Array; @@ -18,7 +12,15 @@ import java.util.Properties; import java.util.UUID; +import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.usertype.ParameterizedType; +import org.hibernate.usertype.UserType; + +import gpc.pgext.hibernate.utils.PgArrayUtils; + public class ArrayType implements UserType, ParameterizedType { + public static final int INTEGER_ARRAY = 90001; public static final int LONG_ARRAY = 90002; public static final int STRING_ARRAY = 90003; @@ -27,7 +29,7 @@ public class ArrayType implements UserType, ParameterizedType { public static final int DOUBLE_ARRAY = 90006; public static final int UUID_ARRAY = 90007; - private static final Map CLASS_TO_SQL_CODE = new HashMap(); + private static final Map, Integer> CLASS_TO_SQL_CODE = new HashMap<>(); static { CLASS_TO_SQL_CODE.put(Integer.class, INTEGER_ARRAY); @@ -151,7 +153,7 @@ public int[] sqlTypes() { @Override public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { Object result = null; - Class typeArrayClass = java.lang.reflect.Array.newInstance(typeClass, 0).getClass(); + Class typeArrayClass = java.lang.reflect.Array.newInstance(typeClass, 0).getClass(); Array sqlArray = rs.getArray(names[0]); if (!rs.wasNull()) { Object array = sqlArray.getArray(); @@ -176,7 +178,7 @@ public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSes } Object[] valueToSet = (Object[]) value; - Class typeArrayClass = java.lang.reflect.Array.newInstance(typeClass, 0).getClass(); + Class typeArrayClass = java.lang.reflect.Array.newInstance(typeClass, 0).getClass(); if (typeClass.isEnum()) { typeArrayClass = Integer[].class; @@ -203,7 +205,7 @@ public Class getTypeClass() { private void ensureBidiMapInitialized() throws HibernateException { try { if (bidiMap == null) { - bidiMap = new BidiEnumMap(typeClass); + bidiMap = new BidiEnumMap((Class) typeClass); } } catch (Exception e) { throw new HibernateException("Unable to create bidirectional enum map for " + typeClass, e); diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/BidiEnumMap.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/BidiEnumMap.groovy new file mode 100644 index 0000000..6a7986f --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/BidiEnumMap.groovy @@ -0,0 +1,61 @@ +package gpc.pgext.hibernate.usertype + +import java.lang.reflect.InvocationTargetException +import java.lang.reflect.Method + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j + +@Slf4j +@CompileStatic +class BidiEnumMap implements Serializable { + + static final String ENUM_ID_ACCESSOR = 'getId' + + private static final long serialVersionUID = 3325751131102095834L + + private final Map enumToKey + private final Map keytoEnum + + BidiEnumMap(Class enumClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + log.debug('Building Bidirectional Enum Map...') + + def enumToKey = new EnumMap(enumClass) + def keytoEnum = new HashMap() + + def idAccessor = getIdAccessor(enumClass) + def values = getEnumValues(enumClass) + + for (Enum value : values) { + def id = idAccessor.invoke(value) + enumToKey.put(value, id) + if (keytoEnum.containsKey(id)) { + log.warn('Duplicate Enum ID [{}] detected for Enum [{}]!', id, enumClass.name) + } + keytoEnum.put(id, value) + } + + this.enumToKey = Collections.unmodifiableMap(enumToKey) + this.keytoEnum = Collections.unmodifiableMap(keytoEnum) + } + + private static E[] getEnumValues(Class enumClass) { + enumClass.enumConstants + } + + private static Method getIdAccessor(Class enumClass) { + def idMethod = enumClass.methods.find { it.name == ENUM_ID_ACCESSOR } + if (!idMethod) { + idMethod = enumClass.getMethod('ordinal') + } + return idMethod + } + + Object getEnumValue(int id) { + keytoEnum.get(id) + } + + int getKey(Object enumValue) { + enumToKey.get(enumValue) as Integer + } +} diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreHelper.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreHelper.groovy new file mode 100644 index 0000000..1dd55ae --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreHelper.groovy @@ -0,0 +1,39 @@ +package gpc.pgext.hibernate.usertype + +import groovy.transform.CompileStatic + +/** + * Converts Maps to String and vice versa according to hstore syntax. + */ +@CompileStatic +class HstoreHelper { + + private static final String K_V_SEPARATOR = '=>' + + private static String escapeQuotes(Object text) { + text.toString().replaceAll('"', '\'') + } + + static String toString(Map m) { + if (!m) return '' + m.collect { k, v -> + "\"${escapeQuotes(k)}\"$K_V_SEPARATOR\"${escapeQuotes(v)}\"" + }.join(', ') + } + + static String asStatement(Map m) { + if (!m) return '' + def token = "\"?\"$K_V_SEPARATOR\"?\"" + Collections.nCopies(m.size(), token).join(', ') + } + + static List asListKeyValue(Map m) { + m ? (m.collectMany { k, v -> [k, v] } as List) : [] as List + } + + static Map toMap(String s) { + !s ? + new HashMap() : + new HstoreParser(s).asMap() + } +} diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreMapType.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreMapType.groovy similarity index 77% rename from src/main/groovy/net/kaleidos/hibernate/usertype/HstoreMapType.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreMapType.groovy index e590786..7466fc6 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreMapType.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreMapType.groovy @@ -1,22 +1,23 @@ -package net.kaleidos.hibernate.usertype - -import groovy.transform.CompileStatic -import org.hibernate.HibernateException -import org.hibernate.engine.spi.SharedSessionContractImplementor -import org.hibernate.usertype.UserType +package gpc.pgext.hibernate.usertype import java.sql.PreparedStatement import java.sql.ResultSet import java.sql.SQLException import java.sql.Types +import groovy.transform.CompileStatic + +import org.hibernate.HibernateException +import org.hibernate.engine.spi.SharedSessionContractImplementor +import org.hibernate.usertype.UserType + @CompileStatic class HstoreMapType implements UserType { static int SQLTYPE = 90011 int[] sqlTypes() { - return SQLTYPE as int[] + SQLTYPE as int[] } Class returnedClass() { @@ -27,11 +28,7 @@ class HstoreMapType implements UserType { if (x == null) { return y == null } - - Map m1 = x as Map - Map m2 = y as Map - - return m1.equals(m2) + (x as Map) == (y as Map) } int hashCode(Object x) throws HibernateException { @@ -39,15 +36,17 @@ class HstoreMapType implements UserType { } Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { - String col = names[0] - String val = rs.getString(col) - - return HstoreHelper.toMap(val) + def col = names[0] + def val = rs.getString(col) + HstoreHelper.toMap(val) } - void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { - String s = HstoreHelper.toString(value as Map) - st.setObject(index, s, Types.OTHER) + void nullSafeSet(PreparedStatement ps, Object value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { + ps.setObject( + index, + HstoreHelper.toString(value as Map), + Types.OTHER + ) } Object deepCopy(Object value) throws HibernateException { diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParseException.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreParseException.groovy similarity index 73% rename from src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParseException.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreParseException.groovy index a5f537c..35d79de 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParseException.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreParseException.groovy @@ -1,4 +1,4 @@ -package net.kaleidos.hibernate.usertype +package gpc.pgext.hibernate.usertype import groovy.transform.CompileStatic @@ -8,6 +8,6 @@ class HstoreParseException extends RuntimeException { private static final long serialVersionUID = 3418828452515857160L HstoreParseException(String error, int position) { - super("Error @${position} : ${error}") + super("Error @$position : $error") } } diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreParser.java similarity index 97% rename from src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java rename to plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreParser.java index 8d62d63..0eb1ad7 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreParser.java +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/HstoreParser.java @@ -1,19 +1,22 @@ -package net.kaleidos.hibernate.usertype; - -import org.postgresql.util.PGobject; -import org.springframework.util.Assert; +package gpc.pgext.hibernate.usertype; +import java.io.Serial; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; +import org.postgresql.util.PGobject; + +import org.springframework.util.Assert; + /** * This class is an extended version of HStore.java from https://code.google.com/p/pg-spring-type-mapper/ */ public class HstoreParser extends PGobject implements Iterable> { + @Serial private static final long serialVersionUID = -2491617655490561600L; private int length; @@ -44,7 +47,7 @@ public void setValue(String rawValue) { } public Map asMap() { - HashMap r = new HashMap(); + HashMap r = new HashMap<>(); try { for (final HStoreIterator iterator = new HStoreIterator(); iterator.hasNext(); ) { final HStoreEntry entry = iterator.rawNext(); @@ -63,7 +66,8 @@ private String replaceEscapePlaceholders(String text) { } private static class HStoreEntry implements Entry { - private String key; + + private final String key; private String value; HStoreEntry(String key, String value) { @@ -136,7 +140,7 @@ public Entry next() throws NoSuchElementException, IllegalStateE /** * Advance in parsing the rawValue string and assign the nextValue - * It creates a new nextElement or assigns null to it, if there are no more elements + * It creates a new nextElement or assigns null to it if there are no more elements * * @throws HstoreParseException */ diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/JsonMapType.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/JsonMapType.groovy similarity index 93% rename from src/main/groovy/net/kaleidos/hibernate/usertype/JsonMapType.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/usertype/JsonMapType.groovy index 9be558d..1dea5b5 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/JsonMapType.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/JsonMapType.groovy @@ -1,20 +1,20 @@ -package net.kaleidos.hibernate.usertype +package gpc.pgext.hibernate.usertype + +import java.lang.reflect.Type +import java.sql.PreparedStatement +import java.sql.ResultSet +import java.sql.SQLException +import java.sql.Types + +import groovy.transform.CompileStatic import com.google.gson.Gson import com.google.gson.GsonBuilder -import groovy.transform.CompileStatic -import org.apache.commons.lang.ObjectUtils import org.hibernate.HibernateException import org.hibernate.engine.spi.SharedSessionContractImplementor import org.hibernate.usertype.UserType import org.postgresql.util.PGobject -import java.lang.reflect.Type -import java.sql.PreparedStatement -import java.sql.ResultSet -import java.sql.SQLException -import java.sql.Types - @CompileStatic class JsonMapType implements UserType { @@ -35,7 +35,7 @@ class JsonMapType implements UserType { @Override boolean equals(Object x, Object y) throws HibernateException { - ObjectUtils.equals(x, y) + Objects.equals(x, y) } @Override @@ -47,7 +47,6 @@ class JsonMapType implements UserType { Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws HibernateException, SQLException { PGobject o = rs.getObject(names[0]) as PGobject String jsonString = o?.value - gson.fromJson(jsonString, userType) } @@ -65,12 +64,10 @@ class JsonMapType implements UserType { if (!value && value != null && value instanceof Map) { return new HashMap() } - if (!value) { return null } - - return new HashMap(value as Map) + new HashMap(value as Map) } @Override diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/JsonbMapType.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/JsonbMapType.groovy similarity index 83% rename from src/main/groovy/net/kaleidos/hibernate/usertype/JsonbMapType.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/usertype/JsonbMapType.groovy index c10a3f6..6fce0f2 100644 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/JsonbMapType.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/usertype/JsonbMapType.groovy @@ -1,4 +1,4 @@ -package net.kaleidos.hibernate.usertype +package gpc.pgext.hibernate.usertype import groovy.transform.CompileStatic diff --git a/plugin/src/main/groovy/gpc/pgext/hibernate/utils/CriteriaUtils.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/utils/CriteriaUtils.groovy new file mode 100644 index 0000000..5afd6a7 --- /dev/null +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/utils/CriteriaUtils.groovy @@ -0,0 +1,77 @@ +package gpc.pgext.hibernate.utils + +import java.lang.reflect.Method + +import groovy.transform.CompileStatic + +import org.hibernate.criterion.Criterion + +import grails.orm.HibernateCriteriaBuilder +import org.grails.orm.hibernate.query.AbstractHibernateCriteriaBuilder + +@CompileStatic +class CriteriaUtils { + + static void validateExpression(HibernateCriteriaBuilder self, String methodName, String propertyName, Object propertyValue) { + if (!validateSimpleExpression(self)) { + throwRuntimeException( + self, + "Call to [$methodName] with propertyName [$propertyName] and value [$propertyValue] is not allowed here." + ) + } + } + + static boolean validateSimpleExpression(HibernateCriteriaBuilder target) { + makeMethodAccessible(AbstractHibernateCriteriaBuilder, 'validateSimpleExpression').invoke(target, new Class[]{}) as boolean + } + + static void throwRuntimeException(HibernateCriteriaBuilder target, String message) { + makeMethodAccessible(AbstractHibernateCriteriaBuilder, 'throwRuntimeException', RuntimeException).invoke( + target, + new IllegalArgumentException(message) + ) + } + + static Method makeMethodAccessible(Class clazz, String methodName, Class... parameterTypes) { + clazz.getDeclaredMethod(methodName, parameterTypes).tap { + accessible = true + } + } + + static Criterion addToCriteria(HibernateCriteriaBuilder self, String methodName, Class criterionClass, String propertyName, Object propertyValue, String operator) { + validateExpression(self, methodName, propertyName, propertyValue) + addToCriteria( + self, + (criterionClass as Class).getDeclaredConstructor(new Class[] {String, Object, String}).newInstance(propertyName, propertyValue, operator) + ) + } + + static Criterion addToCriteria(HibernateCriteriaBuilder self, String methodName, Class criterionClass, String propertyName, Object propertyValue) { + validateExpression(self, methodName, propertyName, propertyValue) + addToCriteria( + self, + (criterionClass as Class).getDeclaredConstructor(new Class[] {String, Object}).newInstance(propertyName, propertyValue) + ) + } + + static Criterion addToCriteria(HibernateCriteriaBuilder target, Criterion criterion) { + makeMethodAccessible(AbstractHibernateCriteriaBuilder, 'addToCriteria', Criterion).invoke( + target, + criterion + ) as Criterion + } + + static String calculatePropertyName(HibernateCriteriaBuilder target, String propertyName) { + makeMethodAccessible(AbstractHibernateCriteriaBuilder, 'calculatePropertyName', String).invoke( + target, + propertyName + ) as String + } + + static Object calculatePropertyValue(HibernateCriteriaBuilder target, Object propertyValue) { + makeMethodAccessible(AbstractHibernateCriteriaBuilder, 'calculatePropertyValue', Object).invoke( + target, + propertyValue + ) + } +} diff --git a/src/main/groovy/net/kaleidos/hibernate/utils/PgArrayUtils.groovy b/plugin/src/main/groovy/gpc/pgext/hibernate/utils/PgArrayUtils.groovy similarity index 50% rename from src/main/groovy/net/kaleidos/hibernate/utils/PgArrayUtils.groovy rename to plugin/src/main/groovy/gpc/pgext/hibernate/utils/PgArrayUtils.groovy index c965dc6..ccd9f5c 100644 --- a/src/main/groovy/net/kaleidos/hibernate/utils/PgArrayUtils.groovy +++ b/plugin/src/main/groovy/gpc/pgext/hibernate/utils/PgArrayUtils.groovy @@ -1,9 +1,10 @@ -package net.kaleidos.hibernate.utils +package gpc.pgext.hibernate.utils + +import java.lang.reflect.Array import groovy.transform.CompileStatic -import org.hibernate.HibernateException -import java.lang.reflect.Array +import org.hibernate.HibernateException /** * Utils for the different criteria queries. @@ -18,7 +19,7 @@ class PgArrayUtils { (Float) : 'float4', (Double) : 'float8', (UUID) : 'uuid', - ] + ] as Map, String> /** * Returns a new array wrapping the parameter value. The type of the array @@ -29,47 +30,26 @@ class PgArrayUtils { * @param mapFunction If non-null, it will transform each object in the array to a given object. * @return an array wrapping the parameter value */ - static Object[] getValueAsArrayOfType(Object targetValue, Class expectedType, MapFunction mapFunction) { - Object[] arrValue + static Object[] getValueAsArrayOfType(Object targetValue, Class expectedType, MapFunction mapFunction) { + if (targetValue instanceof Object[]) return (Object[]) targetValue - if (targetValue instanceof List) { - List valueAsList = targetValue as List - arrValue = Array.newInstance(expectedType, valueAsList.size()) as Object[] - - int count = valueAsList.size() - for (int i = 0; i < count; i++) { - Object object = valueAsList.get(i) - if (expectedType.isInstance(object)) { - arrValue[i] = expectedType.cast(object) - } else if (mapFunction) { - arrValue[i] = expectedType.cast(mapFunction.map(object)) - } else { - throw new HibernateException("criteria doesn't support values of type: " + - targetValue.getClass().getName() + ". Try: " + expectedType + " or List<" + expectedType + "> instead") - } - } - } else if (expectedType.isInstance(targetValue) || mapFunction) { - arrValue = Array.newInstance(expectedType, 1) as Object[] - - if (mapFunction) { - arrValue[0] = expectedType.cast(mapFunction.map(targetValue)) - } else { - arrValue[0] = expectedType.cast(targetValue) - } - } else if (targetValue instanceof Object[]) { - arrValue = targetValue as Object[] - } else { - throw new HibernateException("criteria doesn't support values of type: ${targetValue.class.name}." + - "Try: ${expectedType} or List<${expectedType}> instead") + def items = (targetValue instanceof Collection) ? (targetValue as List) : [targetValue] + def converted = items.collect { o -> + if (expectedType.isInstance(o)) return o + if (mapFunction) return mapFunction.map(o) + throw new HibernateException("criteria doesn't support values of type: ${o?.class?.name}. Try: $expectedType or List<$expectedType> instead") } - return arrValue + + def arr = Array.newInstance(expectedType, converted.size()) + converted.eachWithIndex { v, i -> Array.set(arr, i, expectedType.cast(v)) } + (Object[]) arr } /** * Overloaded version of getValueAsArrayOfType that doesn't use a mapFunction */ static Object[] getValueAsArrayOfType(Object targetValue, Class expectedType) { - return getValueAsArrayOfType(targetValue, expectedType, null) + getValueAsArrayOfType(targetValue, expectedType, null) } /** @@ -90,11 +70,9 @@ class PgArrayUtils { if (typeName != null) { return typeName } - if (clazz.isEnum()) { return 'int' } - - throw new RuntimeException("Type class not valid: ${clazz}") + throw new RuntimeException("Type class not valid: $clazz") } } diff --git a/plugin/src/main/resources/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule b/plugin/src/main/resources/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule new file mode 100644 index 0000000..8e42a21 --- /dev/null +++ b/plugin/src/main/resources/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule @@ -0,0 +1,6 @@ +moduleName=grails-postgresql-extensions +moduleVersion=1.0 +extensionClasses=\ + gpc.pgext.hibernate.postgresql.criteria.ArrayCriterias,\ + gpc.pgext.hibernate.postgresql.criteria.HstoreCriterias,\ + gpc.pgext.hibernate.postgresql.criteria.JsonCriterias \ No newline at end of file diff --git a/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreHelperSpec.groovy b/plugin/src/test/groovy/gpc/pgext/hibernate/usertype/HstoreHelperSpec.groovy similarity index 69% rename from src/test/groovy/net/kaleidos/hibernate/usertype/HstoreHelperSpec.groovy rename to plugin/src/test/groovy/gpc/pgext/hibernate/usertype/HstoreHelperSpec.groovy index ce54b4a..1750664 100644 --- a/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreHelperSpec.groovy +++ b/plugin/src/test/groovy/gpc/pgext/hibernate/usertype/HstoreHelperSpec.groovy @@ -1,4 +1,4 @@ -package net.kaleidos.hibernate.usertype +package gpc.pgext.hibernate.usertype import spock.lang.Issue import spock.lang.Specification @@ -12,7 +12,7 @@ class HstoreHelperSpec extends Specification { def m = value expect: - HstoreHelper.toString(m) == "" + HstoreHelper.toString(m) == '' where: value << [[:], null] @@ -21,7 +21,7 @@ class HstoreHelperSpec extends Specification { void 'non empty map to string'() { setup: def m = [:] - m.foo = "bar" + m.foo = 'bar' expect: HstoreHelper.toString(m) == '"foo"=>"bar"' @@ -30,7 +30,7 @@ class HstoreHelperSpec extends Specification { void 'transform map with double quotes'() { setup: def m = [:] - m['Test "thing"'] = "bar" + m['Test "thing"'] = 'bar' expect: HstoreHelper.toString(m) == '"Test \'thing\'"=>"bar"' @@ -39,8 +39,8 @@ class HstoreHelperSpec extends Specification { void 'map with two values to string'() { setup: def m = [:] - m.foo = "bar" - m.xxx = "Groovy Rocks!" + m.foo = 'bar' + m.xxx = 'Groovy Rocks!' expect: HstoreHelper.toString(m) == '"foo"=>"bar", "xxx"=>"Groovy Rocks!"' @@ -53,7 +53,7 @@ class HstoreHelperSpec extends Specification { m.prop = value expect: - HstoreHelper.toString(m) == "\"prop\"=>\"${value}\"" + HstoreHelper.toString(m) == "\"prop\"=>\"$value\"" where: value << [123, true, null, 999L, new Date(), 87987.8976] @@ -62,7 +62,7 @@ class HstoreHelperSpec extends Specification { void 'map with key and value that contains a comma'() { setup: def m = [:] - m["foo,bar"] = "baz,qux" + m['foo,bar'] = 'baz,qux' expect: HstoreHelper.toString(m) == '"foo,bar"=>"baz,qux"' @@ -71,7 +71,7 @@ class HstoreHelperSpec extends Specification { void 'map with key and value that contains a comma and space'() { setup: def m = [:] - m["foo, bar"] = "baz, qux" + m['foo, bar'] = 'baz, qux' expect: HstoreHelper.toString(m) == '"foo, bar"=>"baz, qux"' @@ -86,8 +86,8 @@ class HstoreHelperSpec extends Specification { result == expected where: - map << [null, [:], ["a": "b"], ["a": "b", "c": "d"], ["a": "b", "c": "d", "e": "f"], ["foo,bar": "baz,qux"]] - expected << ["", "", '"?"=>"?"', '"?"=>"?", "?"=>"?"', '"?"=>"?", "?"=>"?", "?"=>"?"', '"?"=>"?"'] + map << [null, [:], [a: 'b'], [a: 'b', c: 'd'], [a: 'b', c: 'd', e: 'f'], ['foo,bar': 'baz,qux']] + expected << ['', '', '"?"=>"?"', '"?"=>"?", "?"=>"?"', '"?"=>"?", "?"=>"?", "?"=>"?"', '"?"=>"?"'] } @Unroll @@ -99,19 +99,19 @@ class HstoreHelperSpec extends Specification { result == expected where: - map << [null, [:], ["a": "b"], ["a": "b", "c": "d"], ["a": "b", "c": "d", "e": "f"], ["foo,bar": "baz,qux"]] - expected << [[], [], ["a", "b"], ["a", "b", "c", "d"], ["a", "b", "c", "d", "e", "f"], ["foo,bar", "baz,qux"]] + map << [null, [:], [a: 'b'], [a: 'b', c: 'd'], [a: 'b', c: 'd', e: 'f'], ['foo,bar': 'baz,qux']] + expected << [[], [], ['a', 'b'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd', 'e', 'f'], ['foo,bar', 'baz,qux']] } - @Issue("https://github.com/kaleidos/grails-postgresql-extensions/issues/25") @Unroll + @Issue('https://github.com/gpc/grails-postgresql-extensions/issues/25') void 'map with key of type different to String. key: #key'() { setup: def m = [:] - m[key] = "value" + m[key] = 'value' expect: - HstoreHelper.toString(m) == "\"${key}\"=>\"value\"" + HstoreHelper.toString(m) == "\"$key\"=>\"value\"" where: key << [123, true, 999L, new Date(), 87987.8976] diff --git a/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreParserSpec.groovy b/plugin/src/test/groovy/gpc/pgext/hibernate/usertype/HstoreParserSpec.groovy similarity index 86% rename from src/test/groovy/net/kaleidos/hibernate/usertype/HstoreParserSpec.groovy rename to plugin/src/test/groovy/gpc/pgext/hibernate/usertype/HstoreParserSpec.groovy index 6705cf8..f2fd6f9 100644 --- a/src/test/groovy/net/kaleidos/hibernate/usertype/HstoreParserSpec.groovy +++ b/plugin/src/test/groovy/gpc/pgext/hibernate/usertype/HstoreParserSpec.groovy @@ -1,13 +1,14 @@ -package net.kaleidos.hibernate.usertype +package gpc.pgext.hibernate.usertype import spock.lang.Specification import spock.lang.Unroll class HstoreParserSpec extends Specification { + @Unroll - void "AsMap with value populated by constructor"() { + void 'AsMap with value populated by constructor'() { expect: - HstoreParser parser = new HstoreParser(input) + def parser = new HstoreParser(input) def map = parser.asMap() map[expected_key] == expected_value @@ -19,10 +20,12 @@ class HstoreParserSpec extends Specification { } @Unroll - void "AsMap with value populated by setValue"() { + void 'AsMap with value populated by setValue'() { + given: + def parser = new HstoreParser('') + parser.value = input + expect: - HstoreParser parser = new HstoreParser('') - parser.setValue(input) def map = parser.asMap() map[expected_key] == expected_value diff --git a/settings.gradle b/settings.gradle index 6129273..8e1c6b3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,40 @@ -rootProject.name = 'postgresql-extensions' +plugins { + id 'com.gradle.develocity' version '4.1.1' + id 'com.gradle.common-custom-user-data-gradle-plugin' version '2.3' +} + +def isCI = System.getenv().containsKey('CI') +def isLocal = !isCI +def isReproducibleBuild = System.getenv('SOURCE_DATE_EPOCH') != null +if(isReproducibleBuild) { + gradle.settingsEvaluated { + logger.warn('*************** Remote Build Cache Disabled due to Reproducible Build ********************') + logger.warn("Build date will be set to (SOURCE_DATE_EPOCH=${System.getenv("SOURCE_DATE_EPOCH")})") + } +} + +develocity { + server = 'https://ge.grails.org' + buildScan { + tag('gpc') + tag('grails-postgresql-extensions') + publishing.onlyIf { it.authenticated } + uploadInBackground = isLocal + } +} + +buildCache { + local { enabled = (isLocal && !isReproducibleBuild) || (isCI && isReproducibleBuild) } + remote(develocity.buildCache) { + push = isCI + enabled = !isReproducibleBuild + } +} + +rootProject.name = 'postgresql-extensions.ROOT' + +include('plugin') +findProject(':plugin').name = 'grails-postgresql-extensions' + +include('test-app1') +project(':test-app1').projectDir = new File(settingsDir, 'test-apps/app1') diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgILikeCriteriaTestServiceIntegrationSpec.groovy b/src/integration-test/groovy/net/kaleidos/hibernate/array/PgILikeCriteriaTestServiceIntegrationSpec.groovy deleted file mode 100644 index d0f6e4d..0000000 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgILikeCriteriaTestServiceIntegrationSpec.groovy +++ /dev/null @@ -1,45 +0,0 @@ -package net.kaleidos.hibernate.array - -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService - -@Integration -@Rollback -class PgILikeCriteriaTestServiceIntegrationSpec extends Specification { - - @Autowired PgArrayTestSearchService pgArrayTestSearchService - - def setup() { - Like.executeUpdate('delete from Like') - } - - @Unroll - void "check ilike for #movie in an array of strings"() { - setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: []).save(flush: true, failOnError: true) - - when: - def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayILike', movie) - - then: - result.size() == resultSize - - where: - movie | resultSize - "%tarwar%" | 2 - "%ider%" | 1 - "%Suspects%" | 0 - "" | 0 - "%" | 5 - } - -} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreContainsIntegrationSpec.groovy b/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreContainsIntegrationSpec.groovy deleted file mode 100644 index a2da128..0000000 --- a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreContainsIntegrationSpec.groovy +++ /dev/null @@ -1,112 +0,0 @@ -package net.kaleidos.hibernate.hstore - -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.hstore.PgHstoreTestSearchService -import test.hstore.TestHstoreMap - -@Integration -@Rollback -class PgHstoreContainsIntegrationSpec extends Specification { - - @Autowired PgHstoreTestSearchService pgHstoreTestSearchService - - def setup() { - TestHstoreMap.executeUpdate('delete from TestHstoreMap') - } - - void 'Test only one value result 2 different elements'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) - - then: - result.size() == 2 - result.find { it.name == "test1" } != null - result.find { it.name == "test2" } == null - result.find { it.name == "test3" } == null - result.find { it.name == "test4" } != null - - where: - map = ["b": "1"] - } - - void 'Test two values that matches partialy with one element'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) - - then: - result.size() == 1 - result.find { it.name == "test1" } == null - result.find { it.name == "test2" } == null - result.find { it.name == "test3" } == null - result.find { it.name == "test4" } != null - - where: - map = ["b": "1", "c": "test"] - } - - void 'No matches with the same combination key/value'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) - - then: - result.size() == 0 - - where: - map = ["b": "3"] - } - - void 'No matches with the same combination but one of the elements matches'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) - - then: - result.size() == 0 - - where: - map = ["b": "1", "c": "test-otro"] - } - - void 'When empty map returns all elements'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) - - then: - result.size() == 4 - - where: - map = [:] - } -} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreContainsKeyIntegrationSpec.groovy b/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreContainsKeyIntegrationSpec.groovy deleted file mode 100644 index a5610ee..0000000 --- a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreContainsKeyIntegrationSpec.groovy +++ /dev/null @@ -1,51 +0,0 @@ -package net.kaleidos.hibernate.hstore - -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.hstore.PgHstoreTestSearchService -import test.hstore.TestHstoreMap - -@Integration -@Rollback -class PgHstoreContainsKeyIntegrationSpec extends Specification { - - @Autowired PgHstoreTestSearchService pgHstoreTestSearchService - - def setup() { - TestHstoreMap.executeUpdate('delete from TestHstoreMap') - } - - void 'Test find hstore that contains key'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "3"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContainsKey', 'b') - - then: - result.size() == 3 - result.find { it.name == "test1" } != null - result.find { it.name == "test2" } != null - result.find { it.name == "test3" } == null - result.find { it.name == "test4" } != null - } - - void 'Test find hstore that contains other key'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "3"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContainsKey', 'X') - - then: - result.size() == 0 - } -} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreILikeValueFunctionIntegrationSpec.groovy b/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreILikeValueFunctionIntegrationSpec.groovy deleted file mode 100644 index 7ce4f8d..0000000 --- a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreILikeValueFunctionIntegrationSpec.groovy +++ /dev/null @@ -1,51 +0,0 @@ -package net.kaleidos.hibernate.hstore - -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.hstore.PgHstoreTestSearchService -import test.hstore.TestHstoreMap - -@Integration -@Rollback -class PgHstoreILikeValueFunctionIntegrationSpec extends Specification { - - @Autowired PgHstoreTestSearchService pgHstoreTestSearchService - - def setup() { - TestHstoreMap.executeUpdate('delete from TestHstoreMap') - } - - void 'Test find hstore that ilikes value'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "3"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreILikeValue', '%test%') - - then: - result.size() == 3 - result.find { it.name == "test1" } != null - result.find { it.name == "test2" } == null - result.find { it.name == "test3" } != null - result.find { it.name == "test4" } != null - } - - void 'Test find hstore that no ilikes value'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["b": "2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test2"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "Xa", "b": "3"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreILikeValue', '%X') - - then: - result.size() == 0 - } -} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreIsContainedIntegrationSpec.groovy b/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreIsContainedIntegrationSpec.groovy deleted file mode 100644 index c793b8d..0000000 --- a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PgHstoreIsContainedIntegrationSpec.groovy +++ /dev/null @@ -1,78 +0,0 @@ -package net.kaleidos.hibernate.hstore - -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.hstore.PgHstoreTestSearchService -import test.hstore.TestHstoreMap - -@Integration -@Rollback -class PgHstoreIsContainedIntegrationSpec extends Specification { - - @Autowired PgHstoreTestSearchService pgHstoreTestSearchService - - def setup() { - TestHstoreMap.executeUpdate('delete from TestHstoreMap') - } - - void 'No element matches with the empty set'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["d": "10"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreIsContained', map) - - then: - result.size() == 0 - - where: - map = [:] - } - - void 'All elements matches'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["d": "10"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreIsContained', map) - - then: - result.size() == 4 - result.find { it.name == "test1" } != null - result.find { it.name == "test2" } != null - result.find { it.name == "test3" } != null - result.find { it.name == "test4" } != null - - where: - map = ["a": "test", "b": "1", "c": "test", "d": "10"] - } - - void 'Some elements matches'() { - setup: - new TestHstoreMap(name: "test1", testAttributes: ["a": "test", "b": "1"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test2", testAttributes: ["d": "10"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test3", testAttributes: ["a": "test"]).save(flush: true, failOnError: true) - new TestHstoreMap(name: "test4", testAttributes: ["c": "test", "b": "1"]).save(flush: true, failOnError: true) - - when: - def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreIsContained', map) - - then: - result.size() == 3 - result.find { it.name == "test1" } != null - result.find { it.name == "test2" } == null - result.find { it.name == "test3" } != null - result.find { it.name == "test4" } != null - - where: - map = ["a": "test", "b": "1", "c": "test"] - } -} diff --git a/src/main/groovy/grails/postgresql/extensions/GrailsPostgresqlExtensionsGrailsPlugin.groovy b/src/main/groovy/grails/postgresql/extensions/GrailsPostgresqlExtensionsGrailsPlugin.groovy deleted file mode 100644 index d5aa3f5..0000000 --- a/src/main/groovy/grails/postgresql/extensions/GrailsPostgresqlExtensionsGrailsPlugin.groovy +++ /dev/null @@ -1,39 +0,0 @@ -package grails.postgresql.extensions - -import grails.compiler.GrailsCompileStatic -import grails.plugins.Plugin -import net.kaleidos.hibernate.postgresql.criteria.ArrayCriterias -import net.kaleidos.hibernate.postgresql.criteria.HstoreCriterias -import net.kaleidos.hibernate.postgresql.criteria.JsonCriterias - -@GrailsCompileStatic -class GrailsPostgresqlExtensionsGrailsPlugin extends Plugin { - - // the version or versions of Grails the plugin is designed for - def grailsVersion = "3.2.0 > *" - // resources that are excluded from plugin packaging - def pluginExcludes = [ - 'test/**' - ] - - def title = "Grails Postgresql Extensions Plugin" - def author = "Iván López" - def authorEmail = "lopez.ivan@gmail.com" - def description = '''\ -Provides Hibernate user types to support for Postgresql Native Types like Array, HStore, JSON, JSONB,... as well as new criterias to query this native types -''' - - def documentation = "https://github.com/kaleidos/grails-postgresql-extensions/blob/master/README.md" - def license = "APACHE" - def organization = [name: "Kaleidos", url: "http://kaleidos.net"] - def developers = [[name: "Alonso Torres", email: "alonso.javier.torres@gmail.com"]] - def issueManagement = [system: "GITHUB", url: "https://github.com/kaleidos/grails-postgresql-extensions/issues"] - def scm = [url: "https://github.com/kaleidos/grails-postgresql-extensions"] - - void doWithDynamicMethods() { - new ArrayCriterias() - new HstoreCriterias() - new JsonCriterias() - } - -} diff --git a/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreILikeValueFunction.groovy b/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreILikeValueFunction.groovy deleted file mode 100644 index 80411bd..0000000 --- a/src/main/groovy/net/kaleidos/hibernate/criterion/hstore/PgHstoreILikeValueFunction.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package net.kaleidos.hibernate.criterion.hstore - -import groovy.transform.CompileStatic -import org.hibernate.Criteria -import org.hibernate.HibernateException -import org.hibernate.annotations.common.util.StringHelper -import org.hibernate.criterion.CriteriaQuery - -@CompileStatic -class PgHstoreILikeValueFunction extends PgHstoreValueFunction { - - protected PgHstoreILikeValueFunction(String propertyName, Object value) { - super(propertyName, value, "") - } - - @Override - String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - String[] columns = StringHelper.suffix(criteriaQuery.findColumns(propertyName, criteria), "") - for (int i = 0; i < columns.length; i++) { - columns[i] = "text(avals(${columns[i]})) ilike ?" - } - return StringHelper.join(" and ", columns) - } -} diff --git a/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy b/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy deleted file mode 100644 index ec15e9e..0000000 --- a/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/ArrayCriterias.groovy +++ /dev/null @@ -1,204 +0,0 @@ -package net.kaleidos.hibernate.postgresql.criteria - -import grails.orm.HibernateCriteriaBuilder -import net.kaleidos.hibernate.criterion.array.PgArrayExpression -import net.kaleidos.hibernate.criterion.array.PgArrayILikeFunction -import net.kaleidos.hibernate.criterion.array.PgEmptinessExpression - -class ArrayCriterias { - - ArrayCriterias() { - addContainsOperator() - addIsContainedByOperator() - addOverlapsOperator() - addIsEmptyOperator() - addIsNotEmptyOperator() - addIsEmptyOrContainsOperator() - addEqualsOperator() - addNotEqualsOperator() - addILikeOperator() - } - - private void addContainsOperator() { - /** - * Creates a "contains in native array" Criterion based on the specified property name and value - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayContains = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayContains] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "@>")) - } - } - - private void addIsContainedByOperator() { - /** - * Creates a "is contained by in native array" Criterion based on the specified property name and value - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayIsContainedBy = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayIsContainedBy] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "<@")) - } - } - - private void addOverlapsOperator() { - /** - * Creates a "overlap in native array" Criterion based on the specified property name and value - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayOverlaps = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgOverlap] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "&&")) - } - } - - private void addIsEmptyOperator() { - /** - * Creates an "is empty array" Criterion based on the specified property name - * @param propertyName The property name - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayIsEmpty = { String propertyName -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayIsEmpty] with propertyName [" + - propertyName + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - - return addToCriteria(new PgEmptinessExpression(propertyName, "=")) - } - } - - private void addIsNotEmptyOperator() { - /** - * Creates an "is empty array" Criterion based on the specified property name - * @param propertyName The property name - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayIsNotEmpty = { String propertyName -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayIsNotEmpty] with propertyName [" + - propertyName + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - - return addToCriteria(new PgEmptinessExpression(propertyName, "<>")) - } - } - - private void addIsEmptyOrContainsOperator() { - /** - * Creates a "contains in native array" or "is empty native array" Criterion based on the specified property name and value - * If the propertyValue is empty, the 'contains' operator is used and if the propertyValue is not empty, the 'isEmpty' - * operator is used. - * - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayIsEmptyOrContains = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayIsEmptyOrContains] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - if (propertyValue) { - return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "@>")) - } else { - return addToCriteria(new PgEmptinessExpression(propertyName, "=")) - } - } - } - - private void addEqualsOperator() { - /** - * Creates a "equals in native array" Criterion based on the specified property name and value - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayEquals = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayEquals] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "=")) - } - } - - private void addNotEqualsOperator() { - /** - * Creates a "not equals in native array" Criterion based on the specified property name and value - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayNotEquals = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayNotEquals] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgArrayExpression(propertyName, propertyValue, "<>")) - } - } - - private void addILikeOperator() { - /** - * Creates a "ilike in native array" Criterion based on the specified property name and value - * @param propertyName The property name - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgArrayILike = { String propertyName, String propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgArrayILike] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgArrayILikeFunction(propertyName, propertyValue)) - } - } -} diff --git a/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy b/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy deleted file mode 100644 index 951015a..0000000 --- a/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/HstoreCriterias.groovy +++ /dev/null @@ -1,63 +0,0 @@ -package net.kaleidos.hibernate.postgresql.criteria - -import grails.orm.HibernateCriteriaBuilder -import net.kaleidos.hibernate.criterion.hstore.PgHstoreILikeValueFunction -import net.kaleidos.hibernate.criterion.hstore.PgHstoreOperatorExpression -import net.kaleidos.hibernate.criterion.hstore.PgHstoreValueFunction - -class HstoreCriterias { - HstoreCriterias() { - addPgHstoreContainsKey() - addPgHstoreContains() - addPgHstoreIsContained() - addPgHstoreILikeValueFunction() - } - - void addPgHstoreContainsKey() { - HibernateCriteriaBuilder.metaClass.pgHstoreContainsKey = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreContains] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgHstoreValueFunction(propertyName, propertyValue, "exist")) - } - } - - void addPgHstoreContains() { - HibernateCriteriaBuilder.metaClass.pgHstoreContains = { String propertyName, Map values -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreContains] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - propertyName = calculatePropertyName(propertyName) - return addToCriteria(new PgHstoreOperatorExpression(propertyName, values, "@>")) - } - } - - void addPgHstoreIsContained() { - HibernateCriteriaBuilder.metaClass.pgHstoreIsContained = { String propertyName, Map values -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreIsContained] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - propertyName = calculatePropertyName(propertyName) - return addToCriteria(new PgHstoreOperatorExpression(propertyName, values, "<@")) - } - } - - void addPgHstoreILikeValueFunction() { - HibernateCriteriaBuilder.metaClass.pgHstoreILikeValue = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgHstoreILikeValue] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgHstoreILikeValueFunction(propertyName, propertyValue)) - } - } -} diff --git a/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy b/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy deleted file mode 100644 index 896d780..0000000 --- a/src/main/groovy/net/kaleidos/hibernate/postgresql/criteria/JsonCriterias.groovy +++ /dev/null @@ -1,99 +0,0 @@ -package net.kaleidos.hibernate.postgresql.criteria - -import grails.orm.HibernateCriteriaBuilder -import net.kaleidos.hibernate.criterion.json.PgJsonExpression -import net.kaleidos.hibernate.criterion.json.PgJsonbOperator - -class JsonCriterias { - - JsonCriterias() { - addHasFieldValueOperator() - addPgJsonbContainsOperator() - addPgJsonbIsContainedOperator() - addGenericFieldValueOperator() - } - - private void addHasFieldValueOperator() { - /** - * Creates a "json has field value" Criterion based on the specified property name and value - * @param propertyName The property name (json field) - * @param jsonAttribute The json attribute - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgJsonHasFieldValue = { String propertyName, String jsonAttribute, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgJsonHasFieldValue] with propertyName [" + - propertyName + "], jsonAttribute [" + jsonAttribute + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgJsonExpression(propertyName, '->>', jsonAttribute, "=", propertyValue as String)) - } - } - - private void addPgJsonbContainsOperator() { - /** - * Creates a "json constains another json" Criterion based on the specified property name and value - * @param propertyName The property name (jsonb field) - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgJsonbContains = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgJsonContains] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgJsonbOperator(propertyName, propertyValue, "@>")) - } - } - - private void addPgJsonbIsContainedOperator() { - /** - * Creates a "json is contained in another json" Criterion based on the specified property name and value - * @param propertyName The property name (jsonb field) - * @param propertyValue The property value - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgJsonbIsContained = { String propertyName, propertyValue -> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgJsonIsContained] with propertyName [" + - propertyName + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgJsonbOperator(propertyName, propertyValue, "<@")) - } - } - - private void addGenericFieldValueOperator() { - /** - * Creates a "json on field value" Criterion based on the specified property name and value - * @param propertyName The property name (json field) - * @param jsonAttribute The json attribute - * @param jsonOp The json operator (->>, #>, ...) - * @param propertyValue The property value - * @param sqlOp The sql operator (=, <>, ilike, ...) - * @return A Criterion instance - */ - HibernateCriteriaBuilder.metaClass.pgJson = { String propertyName, String jsonOp, String jsonAttribute, String sqlOp, propertyValue-> - if (!validateSimpleExpression()) { - throwRuntimeException(new IllegalArgumentException("Call to [pgJson] with propertyName [" + - propertyName + "], json operator [" + jsonOp + "], jsonAttribute [" + jsonAttribute + "], sql operator [" + sqlOp + "] and value [" + propertyValue + "] not allowed here.")) - } - - propertyName = calculatePropertyName(propertyName) - propertyValue = calculatePropertyValue(propertyValue) - - return addToCriteria(new PgJsonExpression(propertyName, jsonOp, jsonAttribute, sqlOp, propertyValue as String)) - } - } -} diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/BidiEnumMap.groovy b/src/main/groovy/net/kaleidos/hibernate/usertype/BidiEnumMap.groovy deleted file mode 100644 index 4f25090..0000000 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/BidiEnumMap.groovy +++ /dev/null @@ -1,61 +0,0 @@ -package net.kaleidos.hibernate.usertype - -import groovy.transform.CompileDynamic -import groovy.transform.CompileStatic -import groovy.util.logging.Slf4j - -import java.lang.reflect.InvocationTargetException -import java.lang.reflect.Method - -@Slf4j -@CompileStatic -public class BidiEnumMap implements Serializable { - static final String ENUM_ID_ACCESSOR = 'getId' - - private static final long serialVersionUID = 3325751131102095834L - private final Map enumToKey - private final Map keytoEnum - - BidiEnumMap(Class enumClass) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - log.debug 'Building Bidirectional Enum Map...' - - EnumMap enumToKey = new EnumMap(enumClass) - HashMap keytoEnum = new HashMap() - - Method idAccessor = getIdAccessor(enumClass) - Object[] values = getEnumValues(enumClass) - - for (Object value : values) { - Object id = idAccessor.invoke(value) - enumToKey.put(value as Enum, id) - if (keytoEnum.containsKey(id)) { - log.warn(String.format("Duplicate Enum ID '%s' detected for Enum %s!", id, enumClass.name)) - } - keytoEnum.put(id, value) - } - - this.enumToKey = Collections.unmodifiableMap(enumToKey) - this.keytoEnum = Collections.unmodifiableMap(keytoEnum) - } - - @CompileDynamic - private Object[] getEnumValues(Class enumClass) { - enumClass.values() - } - - private Method getIdAccessor(Class enumClass) { - def idMethod = enumClass.methods.find { it.name == 'getId' } - if (!idMethod) { - idMethod = enumClass.getMethod('ordinal') - } - return idMethod - } - - Object getEnumValue(int id) { - keytoEnum.get(id) - } - - int getKey(Object enumValue) { - enumToKey.get(enumValue) as Integer - } -} diff --git a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreHelper.groovy b/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreHelper.groovy deleted file mode 100644 index a80b5a0..0000000 --- a/src/main/groovy/net/kaleidos/hibernate/usertype/HstoreHelper.groovy +++ /dev/null @@ -1,73 +0,0 @@ -package net.kaleidos.hibernate.usertype - -import groovy.transform.CompileStatic - -/** - * Converts Maps to String and vice versa according to hstore syntax. - */ -@CompileStatic -class HstoreHelper { - - private static final String K_V_SEPARATOR = "=>" - - private static String escapeQuotes(String text) { - return text.replaceAll("\"", "'") - } - - static String toString(Map m) { - if (!m) { - return "" - } - - StringBuilder sb = new StringBuilder() - int n = m.size() - for (Object key : m.keySet()) { - String stringKey = String.valueOf(key) - - sb.append('"').append(escapeQuotes(stringKey)).append('"') - sb.append(K_V_SEPARATOR) - sb.append('"').append(escapeQuotes(String.valueOf(m.get(key)))).append('"') - - if (n > 1) { - sb.append(", ") - n-- - } - } - return sb.toString() - } - - static String asStatement(Map m) { - if (!m) { - return "" - } - StringBuilder sb = new StringBuilder() - int n = m.size() - for (String key : m.keySet()) { - sb.append('"?"' + K_V_SEPARATOR + '"?"') - if (n > 1) { - sb.append(", ") - n-- - } - } - return sb.toString() - } - - static List asListKeyValue(Map m) { - List result = new LinkedList() - if (m) { - for (Map.Entry entry : m.entrySet()) { - result << entry.key - result << entry.value - } - } - return result - } - - static Map toMap(String s) { - if (!s) { - return new HashMap() - } - HstoreParser parser = new HstoreParser(s) - return parser.asMap() - } -} diff --git a/test-apps/app1/build.gradle b/test-apps/app1/build.gradle new file mode 100644 index 0000000..02cc950 --- /dev/null +++ b/test-apps/app1/build.gradle @@ -0,0 +1,21 @@ +version = projectVersion +group = 'test' + +apply plugin: 'org.apache.grails.gradle.grails-web' + +dependencies { + + implementation platform("org.apache.grails:grails-bom:$grailsVersion") + + implementation project(':grails-postgresql-extensions') + implementation 'org.apache.grails:grails-data-hibernate5' + implementation 'org.apache.grails:grails-dependencies-starter-web' + + integrationTestImplementation 'org.apache.grails:grails-dependencies-test' +} + +compileJava.options.release = javaVersion.toInteger() + +apply { + from rootProject.layout.projectDirectory.file('gradle/test-config.gradle') +} diff --git a/test-apps/app1/grails-app/conf/application.yml b/test-apps/app1/grails-app/conf/application.yml new file mode 100644 index 0000000..466169f --- /dev/null +++ b/test-apps/app1/grails-app/conf/application.yml @@ -0,0 +1,15 @@ +info: + app: + name: '@info.app.name@' + version: '@info.app.version@' + grailsVersion: '@info.app.grailsVersion@' +dataSource: + pooled: true + jmxExport: true + driverClassName: org.postgresql.Driver + username: postgres_extensions + password: postgres_extensions + url: 'jdbc:postgresql://${POSTGRES_HOST:localhost}:${POSTGRES_PORT:5432}/pg_extensions_test' + dbCreate: create-drop +hibernate: + dialect: gpc.pgext.hibernate.PostgresqlExtensionsDialect diff --git a/test-apps/app1/grails-app/conf/logback-spring.xml b/test-apps/app1/grails-app/conf/logback-spring.xml new file mode 100644 index 0000000..e3b8d89 --- /dev/null +++ b/test-apps/app1/grails-app/conf/logback-spring.xml @@ -0,0 +1,25 @@ + + + + + + + false + + ${CONSOLE_LOG_THRESHOLD} + + + ${CONSOLE_LOG_PATTERN} + ${CONSOLE_LOG_CHARSET} + + + + + + + + + + + + \ No newline at end of file diff --git a/grails-app/conf/spring/resources.groovy b/test-apps/app1/grails-app/conf/spring/resources.groovy similarity index 100% rename from grails-app/conf/spring/resources.groovy rename to test-apps/app1/grails-app/conf/spring/resources.groovy diff --git a/test-apps/app1/grails-app/domain/app/array/TestDouble.groovy b/test-apps/app1/grails-app/domain/app/array/TestDouble.groovy new file mode 100644 index 0000000..2f06ed8 --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/array/TestDouble.groovy @@ -0,0 +1,22 @@ +package app.array + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType + +@ToString +@GrailsCompileStatic +class TestDouble { + + Double[] doubleNumbers + + static mapping = { + doubleNumbers(type: ArrayType, params: [type: Double]) + } + + static constraints = { + doubleNumbers(nullable: true) + } +} diff --git a/grails-app/domain/test/array/TestEnum.groovy b/test-apps/app1/grails-app/domain/app/array/TestEnum.groovy similarity index 64% rename from grails-app/domain/test/array/TestEnum.groovy rename to test-apps/app1/grails-app/domain/app/array/TestEnum.groovy index f67a120..8c9c259 100644 --- a/grails-app/domain/test/array/TestEnum.groovy +++ b/test-apps/app1/grails-app/domain/app/array/TestEnum.groovy @@ -1,9 +1,13 @@ -package test.array +package app.array import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType @ToString +@GrailsCompileStatic class TestEnum { static enum Day { @@ -23,11 +27,10 @@ class TestEnum { Day[] days static mapping = { - days type: ArrayType, params: [type: Day] + days(type: ArrayType, params: [type: Day]) } static constraints = { - days nullable: true + days(nullable: true) } - } diff --git a/test-apps/app1/grails-app/domain/app/array/TestFloat.groovy b/test-apps/app1/grails-app/domain/app/array/TestFloat.groovy new file mode 100644 index 0000000..2a6f488 --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/array/TestFloat.groovy @@ -0,0 +1,22 @@ +package app.array + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType + +@ToString +@GrailsCompileStatic +class TestFloat { + + Float[] floatNumbers + + static mapping = { + floatNumbers(type: ArrayType, params: [type: Float]) + } + + static constraints = { + floatNumbers(nullable: true) + } +} diff --git a/test-apps/app1/grails-app/domain/app/array/TestInteger.groovy b/test-apps/app1/grails-app/domain/app/array/TestInteger.groovy new file mode 100644 index 0000000..8b27811 --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/array/TestInteger.groovy @@ -0,0 +1,22 @@ +package app.array + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType + +@ToString +@GrailsCompileStatic +class TestInteger { + + Integer[] integerNumbers + + static mapping = { + integerNumbers(type: ArrayType, params: [type: Integer]) + } + + static constraints = { + integerNumbers(nullable: true) + } +} diff --git a/test-apps/app1/grails-app/domain/app/array/TestLong.groovy b/test-apps/app1/grails-app/domain/app/array/TestLong.groovy new file mode 100644 index 0000000..e8af71f --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/array/TestLong.groovy @@ -0,0 +1,22 @@ +package app.array + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType + +@ToString +@GrailsCompileStatic +class TestLong { + + Long[] longNumbers + + static mapping = { + longNumbers(type: ArrayType, params: [type: Long]) + } + + static constraints = { + longNumbers(nullable: true) + } +} diff --git a/test-apps/app1/grails-app/domain/app/array/TestString.groovy b/test-apps/app1/grails-app/domain/app/array/TestString.groovy new file mode 100644 index 0000000..f4100bb --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/array/TestString.groovy @@ -0,0 +1,22 @@ +package app.array + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType + +@ToString +@GrailsCompileStatic +class TestString { + + String[] stringArray + + static mapping = { + stringArray(type: ArrayType, params: [type: String]) + } + + static constraints = { + stringArray(nullable: true) + } +} diff --git a/test-apps/app1/grails-app/domain/app/array/TestUuid.groovy b/test-apps/app1/grails-app/domain/app/array/TestUuid.groovy new file mode 100644 index 0000000..1d3974c --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/array/TestUuid.groovy @@ -0,0 +1,22 @@ +package app.array + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType + +@ToString +@GrailsCompileStatic +class TestUuid { + + UUID[] uuidArray + + static mapping = { + uuidArray(type: ArrayType, params: [type: UUID]) + } + + static constraints = { + uuidArray(nullable: true) + } +} diff --git a/grails-app/domain/test/criteria/array/Like.groovy b/test-apps/app1/grails-app/domain/app/criteria/array/Like.groovy similarity index 50% rename from grails-app/domain/test/criteria/array/Like.groovy rename to test-apps/app1/grails-app/domain/app/criteria/array/Like.groovy index 3d1b9c9..0dc7d9d 100644 --- a/grails-app/domain/test/criteria/array/Like.groovy +++ b/test-apps/app1/grails-app/domain/app/criteria/array/Like.groovy @@ -1,9 +1,13 @@ -package test.criteria.array +package app.criteria.array import groovy.transform.ToString -import net.kaleidos.hibernate.usertype.ArrayType + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.ArrayType @ToString +@GrailsCompileStatic class Like { static belongsTo = User @@ -33,15 +37,14 @@ class Like { } static mapping = { - table "pg_extensions_like" - - favoriteNumbers type: ArrayType, params: [type: Integer] - favoriteMovies type: ArrayType, params: [type: String] - favoriteLongNumbers type: ArrayType, params: [type: Long] - favoriteJuices type: ArrayType, params: [type: Juice] - favoriteFloatNumbers type: ArrayType, params: [type: Float] - favoriteDoubleNumbers type: ArrayType, params: [type: Double] - favoriteMovieUUIDs type: ArrayType, params: [type: UUID] + table('pg_extensions_like') + favoriteNumbers(type: ArrayType, params: [type: Integer]) + favoriteMovies(type: ArrayType, params: [type: String]) + favoriteLongNumbers(type: ArrayType, params: [type: Long]) + favoriteJuices(type: ArrayType, params: [type: Juice]) + favoriteFloatNumbers(type: ArrayType, params: [type: Float]) + favoriteDoubleNumbers(type: ArrayType, params: [type: Double]) + favoriteMovieUUIDs(type: ArrayType, params: [type: UUID]) } } diff --git a/test-apps/app1/grails-app/domain/app/criteria/array/User.groovy b/test-apps/app1/grails-app/domain/app/criteria/array/User.groovy new file mode 100644 index 0000000..f9fba91 --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/criteria/array/User.groovy @@ -0,0 +1,18 @@ +package app.criteria.array + +import grails.compiler.GrailsCompileStatic + +@GrailsCompileStatic +class User { + + String name + Like like + + static mapping = { + table('pg_extensions_user') + } + + String toString() { + name + } +} diff --git a/test-apps/app1/grails-app/domain/app/hstore/TestHstoreMap.groovy b/test-apps/app1/grails-app/domain/app/hstore/TestHstoreMap.groovy new file mode 100644 index 0000000..fd24582 --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/hstore/TestHstoreMap.groovy @@ -0,0 +1,26 @@ +package app.hstore + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.HstoreMapType + +@ToString +@GrailsCompileStatic +class TestHstoreMap { + + String name + Integer luckyNumber + + Map testAttributes + + static constraints = { + name(nullable: true) + luckyNumber(nullable: true) + } + + static mapping = { + testAttributes(type: HstoreMapType) + } +} diff --git a/test-apps/app1/grails-app/domain/app/json/TestMapJson.groovy b/test-apps/app1/grails-app/domain/app/json/TestMapJson.groovy new file mode 100644 index 0000000..828cb7b --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/json/TestMapJson.groovy @@ -0,0 +1,22 @@ +package app.json + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.JsonMapType + +@ToString +@GrailsCompileStatic +class TestMapJson { + + Map data + + static constraints = { + data(nullable: true) + } + + static mapping = { + data(type: JsonMapType) + } +} diff --git a/test-apps/app1/grails-app/domain/app/json/TestMapJsonb.groovy b/test-apps/app1/grails-app/domain/app/json/TestMapJsonb.groovy new file mode 100644 index 0000000..5f40e4c --- /dev/null +++ b/test-apps/app1/grails-app/domain/app/json/TestMapJsonb.groovy @@ -0,0 +1,22 @@ +package app.json + +import groovy.transform.ToString + +import grails.compiler.GrailsCompileStatic + +import gpc.pgext.hibernate.usertype.JsonbMapType + +@ToString +@GrailsCompileStatic +class TestMapJsonb { + + Map data + + static constraints = { + data(nullable: true) + } + + static mapping = { + data(type: JsonbMapType) + } +} diff --git a/grails-app/init/grails/postgresql/extensions/Application.groovy b/test-apps/app1/grails-app/init/app/Application.groovy similarity index 74% rename from grails-app/init/grails/postgresql/extensions/Application.groovy rename to test-apps/app1/grails-app/init/app/Application.groovy index a084cd7..0931f30 100644 --- a/grails-app/init/grails/postgresql/extensions/Application.groovy +++ b/test-apps/app1/grails-app/init/app/Application.groovy @@ -1,11 +1,10 @@ -package grails.postgresql.extensions +package app + +import groovy.transform.CompileStatic import grails.boot.GrailsApp import grails.boot.config.GrailsAutoConfiguration -import grails.plugins.metadata.PluginSource -import groovy.transform.CompileStatic -@PluginSource @CompileStatic class Application extends GrailsAutoConfiguration { static void main(String[] args) { diff --git a/test-apps/app1/grails-app/services/app/criteria/array/PgArrayTestSearchService.groovy b/test-apps/app1/grails-app/services/app/criteria/array/PgArrayTestSearchService.groovy new file mode 100644 index 0000000..c0357ea --- /dev/null +++ b/test-apps/app1/grails-app/services/app/criteria/array/PgArrayTestSearchService.groovy @@ -0,0 +1,52 @@ +package app.criteria.array + +class PgArrayTestSearchService { + + List search(String field, String criteriaName, Object value) { + Like.withCriteria { + "$criteriaName"(field, value) + } as List + } + + List search(String field, String criteriaName) { + Like.withCriteria { + "$criteriaName"(field) + } as List + } + + List searchWithJoin(String field, String criteriaName, Object value) { + User.withCriteria { + createAlias('like', 'l') + "$criteriaName"('l.' + field, value) + } as List + } + + List searchWithJoin(String field, String criteriaName) { + User.withCriteria { + createAlias('like', 'l') + "$criteriaName"('l.' + field) + } as List + } + + List searchWithJoinByStringOrInteger(Map params, String criteriaName) { + User.withCriteria { + createAlias('like', 'l') + or { + params.each { k, v -> + "$criteriaName"('l.' + k, v) + } + } + } as List + } + + List searchWithJoinAnd(Map params, String criteriaName) { + User.withCriteria { + createAlias('like', 'l') + and { + params.each { k, v -> + "$criteriaName"('l.' + k, v) + } + } + } as List + } +} diff --git a/test-apps/app1/grails-app/services/app/criteria/hstore/PgHstoreTestSearchService.groovy b/test-apps/app1/grails-app/services/app/criteria/hstore/PgHstoreTestSearchService.groovy new file mode 100644 index 0000000..b4961cb --- /dev/null +++ b/test-apps/app1/grails-app/services/app/criteria/hstore/PgHstoreTestSearchService.groovy @@ -0,0 +1,12 @@ +package app.criteria.hstore + +import app.hstore.TestHstoreMap + +class PgHstoreTestSearchService { + + List search(String field, String criteriaName, Object value) { + TestHstoreMap.withCriteria { + "$criteriaName"(field, value) + } as List + } +} diff --git a/test-apps/app1/grails-app/services/app/criteria/json/PgJsonTestSearchService.groovy b/test-apps/app1/grails-app/services/app/criteria/json/PgJsonTestSearchService.groovy new file mode 100644 index 0000000..e6ee0bd --- /dev/null +++ b/test-apps/app1/grails-app/services/app/criteria/json/PgJsonTestSearchService.groovy @@ -0,0 +1,18 @@ +package app.criteria.json + +import app.json.TestMapJson + +class PgJsonTestSearchService { + + List search(String criteriaName, String field, String jsonAttribute, Object value) { + TestMapJson.withCriteria { + "$criteriaName"(field, jsonAttribute, value.toString()) + } as List + } + + List search(String criteriaName, String field, String jsonOp, String jsonAttribute, String sqlOp, Object value) { + TestMapJson.withCriteria { + "$criteriaName"(field, jsonOp, jsonAttribute, sqlOp, value.toString()) + } as List + } +} diff --git a/test-apps/app1/grails-app/services/app/criteria/json/PgJsonbTestSearchService.groovy b/test-apps/app1/grails-app/services/app/criteria/json/PgJsonbTestSearchService.groovy new file mode 100644 index 0000000..c323b57 --- /dev/null +++ b/test-apps/app1/grails-app/services/app/criteria/json/PgJsonbTestSearchService.groovy @@ -0,0 +1,24 @@ +package app.criteria.json + +import app.json.TestMapJsonb + +class PgJsonbTestSearchService { + + List search(String criteriaName, String field, Object value) { + TestMapJsonb.withCriteria { + "$criteriaName"(field, value) + } as List + } + + List search(String criteriaName, String field, String jsonAttribute, Object value) { + TestMapJsonb.withCriteria { + "$criteriaName"(field, jsonAttribute, value.toString()) + } as List + } + + List search(String criteriaName, String field, String jsonOp, String jsonAttribute, String sqlOp, Object value) { + TestMapJsonb.withCriteria { + "$criteriaName"(field, jsonOp, jsonAttribute, sqlOp, value.toString()) + } as List + } +} diff --git a/test-apps/app1/grails-app/services/app/order/PgOrderService.groovy b/test-apps/app1/grails-app/services/app/order/PgOrderService.groovy new file mode 100644 index 0000000..8b28213 --- /dev/null +++ b/test-apps/app1/grails-app/services/app/order/PgOrderService.groovy @@ -0,0 +1,21 @@ +package app.order + +import app.json.TestMapJsonb + +import static gpc.pgext.hibernate.order.OrderByRandom.byRandom +import static gpc.pgext.hibernate.order.OrderBySqlFormula.sqlFormula + +class PgOrderService { + + List orderByJson() { + TestMapJsonb.withCriteria { + order(sqlFormula('(data->\'name\') desc')) + } as List + } + + List orderByRandom() { + TestMapJsonb.withCriteria { + order(byRandom()) + } as List + } +} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgContainsCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgContainsCriteriaTestServiceIntegrationSpec.groovy similarity index 71% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgContainsCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgContainsCriteriaTestServiceIntegrationSpec.groovy index 65b1dd8..d6f5881 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgContainsCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgContainsCriteriaTestServiceIntegrationSpec.groovy @@ -1,20 +1,23 @@ -package net.kaleidos.hibernate.array +package test.array -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User import org.hibernate.HibernateException -import org.springframework.beans.factory.annotation.Autowired import spock.lang.Specification import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -139,10 +142,10 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { @Unroll void 'search #movie in an array of strings'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings']).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayContains', movie) @@ -151,27 +154,27 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { result.size() == resultSize where: - movie | resultSize - "The Matrix" | 1 - "The Lord of the Rings" | 2 - "Blade Runner" | 2 - "Starwars" | 2 - "The Usual Suspects" | 0 - ["Starwars", "Romeo & Juliet"] | 1 - ["The Lord of the Rings"] | 2 - [] | 4 - ["Starwars", "Romeo & Juliet"] as String[] | 1 - ["The Lord of the Rings"] as String[] | 2 - [] as String[] | 4 + movie | resultSize + 'The Matrix' | 1 + 'The Lord of the Rings' | 2 + 'Blade Runner' | 2 + 'Star Wars' | 2 + 'The Usual Suspects' | 0 + ['Star Wars', 'Romeo & Juliet'] | 1 + ['The Lord of the Rings'] | 2 + [] | 4 + ['Star Wars', 'Romeo & Juliet'] as String[] | 1 + ['The Lord of the Rings'] as String[] | 2 + [] as String[] | 4 } @Unroll void 'search #movie in an array of UUIDs'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Romeo & Juliet", "Casablanca", "Starwars"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Romeo & Juliet', 'Casablanca', 'Star Wars'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovieUUIDs', 'pgArrayContains', movie) @@ -180,18 +183,18 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { result.size() == resultSize where: - movie | resultSize - UuidBuilder.createUUID("The Matrix") | 1 - UuidBuilder.createUUID("The Lord of the Rings") | 2 - UuidBuilder.createUUID("Blade Runner") | 2 - UuidBuilder.createUUID("Starwars") | 2 - UuidBuilder.createUUID("The Usual Suspects") | 0 - UuidBuilder.createUUIDs(["Starwars", "Romeo & Juliet"]) | 1 - UuidBuilder.createUUIDs(["The Lord of the Rings"]) | 2 - [] | 4 - UuidBuilder.createUUIDs(["Starwars", "Romeo & Juliet"]) as UUID[] | 1 - UuidBuilder.createUUIDs(["The Lord of the Rings"]) as UUID[] | 2 - [] as UUID[] | 4 + movie | resultSize + UuidBuilder.createUUID('The Matrix') | 1 + UuidBuilder.createUUID('The Lord of the Rings') | 2 + UuidBuilder.createUUID('Blade Runner') | 2 + UuidBuilder.createUUID('Star Wars') | 2 + UuidBuilder.createUUID('The Usual Suspects') | 0 + UuidBuilder.createUUIDs(['Star Wars', 'Romeo & Juliet']) | 1 + UuidBuilder.createUUIDs(['The Lord of the Rings']) | 2 + [] | 4 + UuidBuilder.createUUIDs(['Star Wars', 'Romeo & Juliet']) as UUID[] | 1 + UuidBuilder.createUUIDs(['The Lord of the Rings']) as UUID[] | 2 + [] as UUID[] | 4 } @Unroll @@ -228,41 +231,41 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars'])).save(flush: true, failOnError: true) + new User(name: 'Jonhny', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoin('favoriteMovies', 'pgArrayContains', movie) then: result.size() == 2 - result.contains(user2) == true - result.contains(user3) == true + result.contains(user2) + result.contains(user3) where: - movie = "Starwars" + movie = 'Star Wars' } void 'search in an array of strings with join with another domain class and or statement'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [3, 4], favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [3, 4], favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoinByStringOrInteger('pgArrayContains', favoriteMovies: movie, favoriteNumbers: number) then: result.size() == 3 - result.contains(user2) == true - result.contains(user3) == true - result.contains(user4) == true + result.contains(user2) + result.contains(user3) + result.contains(user4) where: - movie = "Starwars" + movie = "Star Wars" number = 4 } @@ -274,7 +277,7 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1, "Test"], [1L], [1, 1L]] + number << [['Test'], [1, 'Test'], [1L], [1, 1L]] } void 'search an invalid list inside the array of long'() { @@ -285,7 +288,7 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1L, "Test"], [1], [1L, 1]] + number << [['Test'], [1L, 'Test'], [1], [1L, 1]] } void 'search an invalid list inside the array of float'() { @@ -296,7 +299,7 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1f, "Test"], [1], [1f, 1]] + number << [['Test'], [1f, 'Test'], [1], [1f, 1]] } void 'search an invalid list inside the array of double'() { @@ -307,7 +310,7 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1d, "Test"], [1], [1d, 1]] + number << [['Test'], [1d, 'Test'], [1], [1d, 1]] } void 'search an invalid list inside the array of string'() { @@ -318,7 +321,7 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", 1], [1L], ["Test", 1L]] + movie << [[1], ['Test', 1], [1L], ['Test', 1L]] } void 'search an invalid list inside the array of UUID'() { @@ -329,7 +332,7 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] + movie << [[1], ['Test', UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] } void 'search an invalid list inside the array of enum'() { @@ -340,6 +343,6 @@ class PgContainsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - juice << [["Test"], [Like.Juice.ORANGE, "Test"], [1L], [Like.Juice.APPLE, 1L]] + juice << [['Test'], [Like.Juice.ORANGE, 'Test'], [1L], [Like.Juice.APPLE, 1L]] } } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgEqualsCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgEqualsCriteriaTestServiceIntegrationSpec.groovy similarity index 72% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgEqualsCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgEqualsCriteriaTestServiceIntegrationSpec.groovy index d95cbb0..b71b070 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgEqualsCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgEqualsCriteriaTestServiceIntegrationSpec.groovy @@ -1,20 +1,23 @@ -package net.kaleidos.hibernate.array +package test.array -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User import org.hibernate.HibernateException -import org.springframework.beans.factory.annotation.Autowired import spock.lang.Specification import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -130,10 +133,10 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { @Unroll void 'check equals for #movie in an array of strings'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings']).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) when: @@ -144,24 +147,24 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { where: movie | resultSize - "Starwars" | 1 - ["Starwars"] | 1 - ["Starwars"] as String[] | 1 - "The Usual Suspects" | 0 - ["Spiderman", "Blade Runner", "Starwars"] | 1 + 'Star Wars' | 1 + ['Star Wars'] | 1 + ['Star Wars'] as String[] | 1 + 'The Usual Suspects' | 0 + ['Spiderman', 'Blade Runner', 'Star Wars'] | 1 [] | 1 - ["The Matrix", "The Lord of the Rings"] as String[] | 1 - ["The Lord of the Rings", "The Matrix"] as String[] | 0 + ['The Matrix', 'The Lord of the Rings'] as String[] | 1 + ['The Lord of the Rings', 'The Matrix'] as String[] | 0 [] as String[] | 1 } @Unroll void 'check equals for #movie in an array of UUIDs'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Starwars"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Star Wars'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) when: @@ -172,14 +175,14 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { where: movie | resultSize - UuidBuilder.createUUID("Starwars") | 1 - UuidBuilder.createUUIDs(["Starwars"]) | 1 - UuidBuilder.createUUIDs(["Starwars"]) as UUID[] | 1 - UuidBuilder.createUUID("The Usual Suspects") | 0 - UuidBuilder.createUUIDs(["Spiderman", "Blade Runner", "Starwars"]) | 1 + UuidBuilder.createUUID('Star Wars') | 1 + UuidBuilder.createUUIDs(['Star Wars']) | 1 + UuidBuilder.createUUIDs(['Star Wars']) as UUID[] | 1 + UuidBuilder.createUUID('The Usual Suspects') | 0 + UuidBuilder.createUUIDs(['Spiderman', 'Blade Runner', 'Star Wars']) | 1 [] | 1 - UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"]) as UUID[] | 1 - UuidBuilder.createUUIDs(["The Lord of the Rings", "The Matrix"]) as UUID[] | 0 + UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings']) as UUID[] | 1 + UuidBuilder.createUUIDs(['The Lord of the Rings', 'The Matrix']) as UUID[] | 0 [] as UUID[] | 1 } @@ -208,41 +211,41 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoin('favoriteMovies', 'pgArrayEquals', movie) then: result.size() == 2 - result.contains(user2) == true - result.contains(user3) == true + result.contains(user2) + result.contains(user3) where: - movie = ["Spiderman", "Blade Runner", "Starwars"] + movie = ['Spiderman', 'Blade Runner', 'Star Wars'] } void 'search in an array of strings with join with another domain class and or statement'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoinByStringOrInteger('pgArrayEquals', favoriteMovies: movie, favoriteNumbers: number) then: result.size() == 3 - result.contains(user2) == true - result.contains(user3) == true - result.contains(user4) == true + result.contains(user2) + result.contains(user3) + result.contains(user4) where: - movie = ["Spiderman", "Blade Runner", "Starwars"] + movie = ['Spiderman', 'Blade Runner', 'Star Wars'] number = [9, 4] } @@ -254,7 +257,7 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1, "Test"], [1L], [1, 1L]] + number << [['Test'], [1, 'Test'], [1L], [1, 1L]] } void 'search an invalid list inside the array of long'() { @@ -265,7 +268,7 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1L, "Test"], [1], [1L, 1]] + number << [['Test'], [1L, 'Test'], [1], [1L, 1]] } void 'search an invalid list inside the array of float'() { @@ -276,7 +279,7 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1f, "Test"], [1], [1f, 1]] + number << [['Test'], [1f, 'Test'], [1], [1f, 1]] } void 'search an invalid list inside the array of double'() { @@ -287,7 +290,7 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1d, "Test"], [1], [1d, 1]] + number << [['Test'], [1d, 'Test'], [1], [1d, 1]] } void 'search an invalid list inside the array of string'() { @@ -298,7 +301,7 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", 1], [1L], ["Test", 1L]] + movie << [[1], ['Test', 1], [1L], ['Test', 1L]] } void 'search an invalid list inside the array of UUID'() { @@ -309,7 +312,7 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] + movie << [[1], ['Test', UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] } void 'search an invalid list inside the array of enum'() { @@ -320,6 +323,6 @@ class PgEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - juice << [["Test"], [Like.Juice.ORANGE, "Test"], [1L], [Like.Juice.APPLE, 1L]] + juice << [['Test'], [Like.Juice.ORANGE, 'Test'], [1L], [Like.Juice.APPLE, 1L]] } } diff --git a/test-apps/app1/src/integration-test/groovy/test/array/PgILikeCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgILikeCriteriaTestServiceIntegrationSpec.groovy new file mode 100644 index 0000000..1b19c85 --- /dev/null +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgILikeCriteriaTestServiceIntegrationSpec.groovy @@ -0,0 +1,47 @@ +package test.array + +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import spock.lang.Specification +import spock.lang.Unroll + +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + +@Rollback +@Integration +class PgILikeCriteriaTestServiceIntegrationSpec extends Specification { + + @Autowired + PgArrayTestSearchService pgArrayTestSearchService + + def setup() { + Like.executeUpdate('delete from Like') + } + + @Unroll + void 'check ilike for #movie in an array of strings'() { + setup: + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings']).save(flush: true, failOnError: true) + new Like(favoriteMovies: []).save(flush: true, failOnError: true) + + when: + def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayILike', movie) + + then: + result.size() == resultSize + + where: + movie | resultSize + '%tar War%' | 2 + '%ider%' | 1 + '%Suspects%' | 0 + '' | 0 + '%' | 5 + } +} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsContainedByCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgIsContainedByCriteriaTestServiceIntegrationSpec.groovy similarity index 80% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsContainedByCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgIsContainedByCriteriaTestServiceIntegrationSpec.groovy index 6564fad..8ce46c3 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsContainedByCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgIsContainedByCriteriaTestServiceIntegrationSpec.groovy @@ -1,20 +1,23 @@ -package net.kaleidos.hibernate.array +package test.array -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User import org.hibernate.HibernateException -import org.springframework.beans.factory.annotation.Autowired import spock.lang.Specification import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -138,10 +141,10 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { @Unroll void 'search #movie in an array of strings'() { setup: - new Like(favoriteMovies: ["A", "B", "C", "D", "E"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["D", "E", "F", "G"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["A", "Z"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["B"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['A', 'B', 'C', 'D', 'E']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['D', 'E', 'F', 'G']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['A', 'Z']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['B']).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayIsContainedBy', movie) @@ -151,24 +154,24 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { where: movie | resultSize - "A" | 0 - "B" | 1 - ["A", "Z"] | 1 - ["B", "D", "E", "F", "G"] | 2 - ["A", "B", "C", "D", "E", "F", "G", "H", "I", "Z"] | 4 + 'A' | 0 + 'B' | 1 + ['A', 'Z'] | 1 + ['B', 'D', 'E', 'F', 'G'] | 2 + ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'Z'] | 4 [] | 0 - ["A", "Z"] as String[] | 1 - ["B", "D", "E", "F", "G"] as String[] | 2 + ['A', 'Z'] as String[] | 1 + ['B', 'D', 'E', 'F', 'G'] as String[] | 2 [] as String[] | 0 } @Unroll void 'search #movie in an array of UUIDs'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["A", "B", "C", "D", "E"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["D", "E", "F", "G"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["A", "Z"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["B"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['A', 'B', 'C', 'D', 'E'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['D', 'E', 'F', 'G'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['A', 'Z'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['B'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovieUUIDs', 'pgArrayIsContainedBy', movie) @@ -178,14 +181,14 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { where: movie | resultSize - UuidBuilder.createUUID("A") | 0 - UuidBuilder.createUUID("B") | 1 - UuidBuilder.createUUIDs(["A", "Z"]) | 1 - UuidBuilder.createUUIDs(["B", "D", "E", "F", "G"]) | 2 - UuidBuilder.createUUIDs(["A", "B", "C", "D", "E", "F", "G", "H", "I", "Z"]) | 4 + UuidBuilder.createUUID('A') | 0 + UuidBuilder.createUUID('B') | 1 + UuidBuilder.createUUIDs(['A', 'Z']) | 1 + UuidBuilder.createUUIDs(['B', 'D', 'E', 'F', 'G']) | 2 + UuidBuilder.createUUIDs(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'Z']) | 4 [] | 0 - UuidBuilder.createUUIDs(["A", "Z"]) as UUID[] | 1 - UuidBuilder.createUUIDs(["B", "D", "E", "F", "G"]) as UUID[] | 2 + UuidBuilder.createUUIDs(['A', 'Z']) as UUID[] | 1 + UuidBuilder.createUUIDs(['B', 'D', 'E', 'F', 'G']) as UUID[] | 2 [] as UUID[] | 0 } @@ -224,41 +227,41 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'Abe', like: new Like(favoriteMovies: ["A", "B", "D"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Bernard', like: new Like(favoriteMovies: ["A", "C"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Carl', like: new Like(favoriteMovies: ["A"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Dave', like: new Like(favoriteMovies: ["A", "C", "D"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'Abe', like: new Like(favoriteMovies: ['A', 'B', 'D'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Bernard', like: new Like(favoriteMovies: ['A', 'C'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Carl', like: new Like(favoriteMovies: ['A'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Dave', like: new Like(favoriteMovies: ['A', 'C', 'D'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoin('favoriteMovies', 'pgArrayIsContainedBy', movies) then: result.size() == 2 - result.contains(user2) == true - result.contains(user3) == true + result.contains(user2) + result.contains(user3) where: - movies = ["A", "B", "C"] + movies = ['A', 'B', 'C'] } void 'search in an array of strings with join with another domain class and or statement'() { setup: - def user1 = new User(name: 'Abe', like: new Like(favoriteNumbers: [1, 3], favoriteMovies: ["A", "B", "D"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Bernard', like: new Like(favoriteNumbers: [1], favoriteMovies: ["A", "C"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Carl', like: new Like(favoriteNumbers: [2], favoriteMovies: ["A"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Dave', like: new Like(favoriteNumbers: [1, 2], favoriteMovies: ["A", "B", "D"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'Abe', like: new Like(favoriteNumbers: [1, 3], favoriteMovies: ['A', 'B', 'D'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Bernard', like: new Like(favoriteNumbers: [1], favoriteMovies: ['A', 'C'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Carl', like: new Like(favoriteNumbers: [2], favoriteMovies: ['A'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Dave', like: new Like(favoriteNumbers: [1, 2], favoriteMovies: ['A', 'B', 'D'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoinByStringOrInteger('pgArrayIsContainedBy', favoriteMovies: movies, favoriteNumbers: numbers) then: result.size() == 3 - result.contains(user2) == true - result.contains(user3) == true - result.contains(user4) == true + result.contains(user2) + result.contains(user3) + result.contains(user4) where: - movies = ["A", "B", "C"] + movies = ['A', 'B', 'C'] numbers = [1, 2] } @@ -270,7 +273,7 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1, "Test"], [1L], [1, 1L]] + number << [['Test'], [1, 'Test'], [1L], [1, 1L]] } void 'search a invalid list inside the array of long'() { @@ -281,7 +284,7 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1L, "Test"], [1], [1L, 1]] + number << [['Test'], [1L, 'Test'], [1], [1L, 1]] } void 'search a invalid list inside the array of float'() { @@ -292,7 +295,7 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1f, "Test"], [1], [1f, 1]] + number << [['Test'], [1f, 'Test'], [1], [1f, 1]] } void 'search a invalid list inside the array of double'() { @@ -303,7 +306,7 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1d, "Test"], [1], [1d, 1]] + number << [['Test'], [1d, 'Test'], [1], [1d, 1]] } void 'search a invalid list inside the array of string'() { @@ -314,7 +317,7 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", 1], [1L], ["Test", 1L]] + movie << [[1], ['Test', 1], [1L], ['Test', 1L]] } void 'search an invalid list inside the array of UUID'() { @@ -325,7 +328,7 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] + movie << [[1], ['Test', UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] } void 'search an invalid list juice inside the array of enum'() { @@ -336,7 +339,6 @@ class PgIsContainedByCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - juice << [["Test"], ["Test", Like.Juice.ORANGE], [1L], ["Test", 1L]] + juice << [['Test'], ['Test', Like.Juice.ORANGE], [1L], ['Test', 1L]] } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsEmptyCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgIsEmptyCriteriaTestServiceIntegrationSpec.groovy similarity index 88% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsEmptyCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgIsEmptyCriteriaTestServiceIntegrationSpec.groovy index cd4c80f..1a692d0 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsEmptyCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgIsEmptyCriteriaTestServiceIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.array +package test.array + +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired import grails.gorm.transactions.Rollback import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration @Rollback +@Integration class PgIsEmptyCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -73,7 +76,7 @@ class PgIsEmptyCriteriaTestServiceIntegrationSpec extends Specification { void 'search for empty string arrays'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) @@ -86,7 +89,7 @@ class PgIsEmptyCriteriaTestServiceIntegrationSpec extends Specification { void 'search for empty UUID arrays'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) @@ -112,7 +115,7 @@ class PgIsEmptyCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: [])).save(flush: true, failOnError: true) def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: [])).save(flush: true, failOnError: true) @@ -121,7 +124,7 @@ class PgIsEmptyCriteriaTestServiceIntegrationSpec extends Specification { then: result.size() == 2 - result.contains(user2) == true - result.contains(user3) == true + result.contains(user2) + result.contains(user3) } } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec.groovy similarity index 77% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec.groovy index 54df9f1..5b0ce99 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec.groovy @@ -1,16 +1,18 @@ -package net.kaleidos.hibernate.array +package test.array -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User import spock.lang.Specification import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec extends Specification { @Autowired PgArrayTestSearchService pgArrayTestSearchService @@ -119,10 +121,10 @@ class PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec extends Specificatio @Unroll void 'search #movie in an array of strings'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings']).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayIsEmptyOrContains', movie) @@ -131,23 +133,23 @@ class PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec extends Specificatio result.size() == resultSize where: - movie | resultSize - ["The Matrix"] | 1 - ["Starwars", "Romeo & Juliet"] | 1 - ["The Lord of the Rings"] | 2 - [] | 1 - ["Starwars", "Romeo & Juliet"] as String[] | 1 - ["The Lord of the Rings"] as String[] | 2 - [] as String[] | 1 + movie | resultSize + ['The Matrix'] | 1 + ['Star Wars', 'Romeo & Juliet'] | 1 + ['The Lord of the Rings'] | 2 + [] | 1 + ['Star Wars', 'Romeo & Juliet'] as String[] | 1 + ['The Lord of the Rings'] as String[] | 2 + [] as String[] | 1 } @Unroll void 'search #movie in an array of UUIDs'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Romeo & Juliet", "Casablanca", "Starwars"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Romeo & Juliet', 'Casablanca', 'Star Wars'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovieUUIDs', 'pgArrayIsEmptyOrContains', movie) @@ -156,14 +158,14 @@ class PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec extends Specificatio result.size() == resultSize where: - movie | resultSize - UuidBuilder.createUUIDs(["The Matrix"]) | 1 - UuidBuilder.createUUIDs(["Starwars", "Romeo & Juliet"]) | 1 - UuidBuilder.createUUIDs(["The Lord of the Rings"]) | 2 - [] | 1 - UuidBuilder.createUUIDs(["Starwars", "Romeo & Juliet"]) as UUID[] | 1 - UuidBuilder.createUUIDs(["The Lord of the Rings"]) as UUID[] | 2 - [] as UUID[] | 1 + movie | resultSize + UuidBuilder.createUUIDs(['The Matrix']) | 1 + UuidBuilder.createUUIDs(['Star Wars', 'Romeo & Juliet']) | 1 + UuidBuilder.createUUIDs(['The Lord of the Rings']) | 2 + [] | 1 + UuidBuilder.createUUIDs(['Star Wars', 'Romeo & Juliet']) as UUID[] | 1 + UuidBuilder.createUUIDs(['The Lord of the Rings']) as UUID[] | 2 + [] as UUID[] | 1 } @Unroll @@ -190,10 +192,10 @@ class PgIsEmptyOrContainsCriteriaTestServiceIntegrationSpec extends Specificatio @Unroll void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: [])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "Spiderman"])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'Spiderman'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoin('favoriteMovies', 'pgArrayIsEmptyOrContains', movie) diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsNotEmptyCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgIsNotEmptyCriteriaTestServiceIntegrationSpec.groovy similarity index 88% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsNotEmptyCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgIsNotEmptyCriteriaTestServiceIntegrationSpec.groovy index b8030ba..697837b 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgIsNotEmptyCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgIsNotEmptyCriteriaTestServiceIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.array +package test.array + +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired import grails.gorm.transactions.Rollback import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration @Rollback +@Integration class PgIsNotEmptyCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -73,7 +76,7 @@ class PgIsNotEmptyCriteriaTestServiceIntegrationSpec extends Specification { void 'search for empty string arrays'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) @@ -86,7 +89,7 @@ class PgIsNotEmptyCriteriaTestServiceIntegrationSpec extends Specification { void 'search for empty UUID arrays'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) @@ -112,7 +115,7 @@ class PgIsNotEmptyCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: [])).save(flush: true, failOnError: true) def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: [])).save(flush: true, failOnError: true) @@ -121,6 +124,6 @@ class PgIsNotEmptyCriteriaTestServiceIntegrationSpec extends Specification { then: result.size() == 1 - result.contains(user1) == true + result.contains(user1) } } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgNotEqualsCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgNotEqualsCriteriaTestServiceIntegrationSpec.groovy similarity index 73% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgNotEqualsCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgNotEqualsCriteriaTestServiceIntegrationSpec.groovy index dd50025..e79b5f3 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgNotEqualsCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgNotEqualsCriteriaTestServiceIntegrationSpec.groovy @@ -1,20 +1,23 @@ -package net.kaleidos.hibernate.array +package test.array -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User import org.hibernate.HibernateException -import org.springframework.beans.factory.annotation.Autowired import spock.lang.Specification import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -120,9 +123,9 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { @Unroll void 'check equals for #movie in an array of strings'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Starwars"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Star Wars']).save(flush: true, failOnError: true) new Like(favoriteMovies: []).save(flush: true, failOnError: true) when: @@ -132,22 +135,22 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { result.size() == resultSize where: - movie | resultSize - "Starwars" | 3 - ["Starwars"] | 3 - ["Starwars"] as String[] | 3 - "The Usual Suspects" | 4 - ["Spiderman", "Blade Runner", "Starwars"] | 3 - ["Spiderman", "Starwars", "Blade Runner"] | 4 - [] | 3 + movie | resultSize + 'Star Wars' | 3 + ['Star Wars'] | 3 + ['Star Wars'] as String[] | 3 + 'The Usual Suspects' | 4 + ['Spiderman', 'Blade Runner', 'Star Wars'] | 3 + ['Spiderman', 'Star Wars', 'Blade Runner'] | 4 + [] | 3 } @Unroll void 'check equals for #movie in an array of uuids'() { setup: - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(["Starwars"])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + new Like(favoriteMovieUUIDs: UuidBuilder.createUUIDs(['Star Wars'])).save(flush: true, failOnError: true) new Like(favoriteMovieUUIDs: []).save(flush: true, failOnError: true) when: @@ -157,14 +160,14 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { result.size() == resultSize where: - movie | resultSize - UuidBuilder.createUUID("Starwars") | 3 - UuidBuilder.createUUIDs(["Starwars"]) | 3 - UuidBuilder.createUUIDs(["Starwars"]) as UUID[] | 3 - UuidBuilder.createUUID("The Usual Suspects") | 4 - UuidBuilder.createUUIDs(["Spiderman", "Blade Runner", "Starwars"]) | 3 - UuidBuilder.createUUIDs(["Spiderman", "Starwars", "Blade Runner"]) | 4 - [] | 3 + movie | resultSize + UuidBuilder.createUUID('Star Wars') | 3 + UuidBuilder.createUUIDs(['Star Wars']) | 3 + UuidBuilder.createUUIDs(['Star Wars']) as UUID[] | 3 + UuidBuilder.createUUID('The Usual Suspects') | 4 + UuidBuilder.createUUIDs(['Spiderman', 'Blade Runner', 'Star Wars']) | 3 + UuidBuilder.createUUIDs(['Spiderman', 'Star Wars', 'Blade Runner']) | 4 + [] | 3 } @Unroll @@ -191,40 +194,40 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoin('favoriteMovies', 'pgArrayNotEquals', movie) then: result.size() == 2 - result.contains(user1) == true - result.contains(user4) == true + result.contains(user1) + result.contains(user4) where: - movie = ["Spiderman", "Blade Runner", "Starwars"] + movie = ['Spiderman', 'Blade Runner', 'Star Wars'] } void 'search in an array of strings with join with another domain class and or statement'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoinByStringOrInteger('pgArrayNotEquals', favoriteMovies: movie, favoriteNumbers: number) then: result.size() == 2 - result.contains(user1) == true - result.contains(user4) == true + result.contains(user1) + result.contains(user4) where: - movie = ["Spiderman", "Blade Runner", "Starwars"] + movie = ['Spiderman', 'Blade Runner', 'Star Wars'] number = [5, 17, 9, 6] } @@ -236,7 +239,7 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1, "Test"], [1L], [1, 1L]] + number << [['Test'], [1, 'Test'], [1L], [1, 1L]] } void 'search an invalid list inside the array of long'() { @@ -247,7 +250,7 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1L, "Test"], [1], [1L, 1]] + number << [['Test'], [1L, 'Test'], [1], [1L, 1]] } void 'search an invalid list inside the array of float'() { @@ -258,7 +261,7 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1f, "Test"], [1], [1f, 1]] + number << [['Test'], [1f, 'Test'], [1], [1f, 1]] } void 'search an invalid list inside the array of double'() { @@ -269,7 +272,7 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1d, "Test"], [1], [1d, 1]] + number << [['Test'], [1d, 'Test'], [1], [1d, 1]] } void 'search an invalid list inside the array of string'() { @@ -280,7 +283,7 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", 1], [1L], ["Test", 1L], [UUID.randomUUID()]] + movie << [[1], ['Test', 1], [1L], ['Test', 1L], [UUID.randomUUID()]] } void 'search an invalid list inside the array of UUID'() { @@ -291,7 +294,7 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] + movie << [[1], ['Test', UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] } void 'search an invalid list inside the array of enum'() { @@ -302,6 +305,6 @@ class PgNotEqualsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - juice << [["Test"], [Like.Juice.ORANGE, "Test"], [1L], [Like.Juice.APPLE, 1L]] + juice << [['Test'], [Like.Juice.ORANGE, 'Test'], [1L], [Like.Juice.APPLE, 1L]] } } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgOverlapsCriteriaTestServiceIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PgOverlapsCriteriaTestServiceIntegrationSpec.groovy similarity index 76% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PgOverlapsCriteriaTestServiceIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PgOverlapsCriteriaTestServiceIntegrationSpec.groovy index d184a6e..ba8ff80 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PgOverlapsCriteriaTestServiceIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PgOverlapsCriteriaTestServiceIntegrationSpec.groovy @@ -1,20 +1,23 @@ -package net.kaleidos.hibernate.array +package test.array -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.criteria.array.Like +import app.criteria.array.PgArrayTestSearchService +import app.criteria.array.User import org.hibernate.HibernateException -import org.springframework.beans.factory.annotation.Autowired import spock.lang.Specification import spock.lang.Unroll -import test.criteria.array.Like -import test.criteria.array.PgArrayTestSearchService -import test.criteria.array.User -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { - @Autowired PgArrayTestSearchService pgArrayTestSearchService + @Autowired + PgArrayTestSearchService pgArrayTestSearchService def setup() { User.executeUpdate('delete from User') @@ -140,10 +143,10 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { @Unroll void 'search #movie in an array of strings'() { setup: - new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"]).save(flush: true, failOnError: true) - new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"]).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars']).save(flush: true, failOnError: true) + new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings']).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.search('favoriteMovies', 'pgArrayOverlaps', movie) @@ -152,18 +155,18 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { result.size() == resultSize where: - movie | resultSize - "The Matrix" | 1 - "The Lord of the Rings" | 2 - "Blade Runner" | 2 - "Starwars" | 2 - "The Usual Suspects" | 0 - ["Starwars", "Romeo & Juliet"] | 3 - ["The Lord of the Rings"] | 2 - [] | 0 - ["Starwars", "Romeo & Juliet"] as String[] | 3 - ["The Lord of the Rings"] as String[] | 2 - [] as String[] | 0 + movie | resultSize + 'The Matrix' | 1 + 'The Lord of the Rings' | 2 + 'Blade Runner' | 2 + 'Star Wars' | 2 + 'The Usual Suspects' | 0 + ['Star Wars', 'Romeo & Juliet'] | 3 + ['The Lord of the Rings'] | 2 + [] | 0 + ['Star Wars', 'Romeo & Juliet'] as String[] | 3 + ['The Lord of the Rings'] as String[] | 2 + [] as String[] | 0 } @Unroll @@ -200,41 +203,41 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { void 'search in an array of strings with join with another domain class'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoin('favoriteMovies', 'pgArrayOverlaps', movie) then: result.size() == 3 - result.contains(user2) == true - result.contains(user3) == true - result.contains(user4) == true + result.contains(user2) + result.contains(user3) + result.contains(user4) where: - movie = ["Starwars", "Romeo & Juliet"] + movie = ['Star Wars', 'Romeo & Juliet'] } void 'search in an array of strings with join with another domain class and or statement'() { setup: - def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ["The Matrix", "The Lord of the Rings"])).save(flush: true, failOnError: true) - def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ["Spiderman", "Blade Runner", "Starwars"])).save(flush: true, failOnError: true) - def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [3, 4], favoriteMovies: ["Romeo & Juliet", "Casablanca", "Starwars"])).save(flush: true, failOnError: true) - def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ["Romeo & Juliet", "Blade Runner", "The Lord of the Rings"])).save(flush: true, failOnError: true) + def user1 = new User(name: 'John', like: new Like(favoriteNumbers: [3, 7], favoriteMovies: ['The Matrix', 'The Lord of the Rings'])).save(flush: true, failOnError: true) + def user2 = new User(name: 'Peter', like: new Like(favoriteNumbers: [5, 17, 9, 6], favoriteMovies: ['Spiderman', 'Blade Runner', 'Star Wars'])).save(flush: true, failOnError: true) + def user3 = new User(name: 'Mary', like: new Like(favoriteNumbers: [3, 4], favoriteMovies: ['Romeo & Juliet', 'Casablanca', 'Star Wars'])).save(flush: true, failOnError: true) + def user4 = new User(name: 'Jonhny', like: new Like(favoriteNumbers: [9, 4], favoriteMovies: ['Romeo & Juliet', 'Blade Runner', 'The Lord of the Rings'])).save(flush: true, failOnError: true) when: def result = pgArrayTestSearchService.searchWithJoinAnd('pgArrayOverlaps', favoriteMovies: movie, favoriteNumbers: number) then: result.size() == 2 - result.contains(user2) == true - result.contains(user4) == true + result.contains(user2) + result.contains(user4) where: - movie = ["Starwars", "Romeo & Juliet"] + movie = ['Star Wars', 'Romeo & Juliet'] number = [9] } @@ -247,7 +250,7 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1, "Test"], [1L], [1, 1L]] + number << [['Test'], [1, 'Test'], [1L], [1, 1L]] } @Unroll @@ -259,7 +262,7 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - number << [["Test"], [1L, "Test"], [1], [1L, 1]] + number << [['Test'], [1L, 'Test'], [1], [1L, 1]] } @Unroll @@ -271,7 +274,7 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", 1], [1L], ["Test", 1L]] + movie << [[1], ['Test', 1], [1L], ['Test', 1L]] } @Unroll @@ -283,7 +286,7 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - movie << [[1], ["Test", UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] + movie << [[1], ['Test', UUID.randomUUID()], [1L], [UUID.randomUUID(), 1L]] } @Unroll @@ -295,6 +298,6 @@ class PgOverlapsCriteriaTestServiceIntegrationSpec extends Specification { thrown HibernateException where: - juice << [["Test"], [Like.Juice.ORANGE, "Test"], [1L], [Like.Juice.APPLE, 1L]] + juice << [['Test'], [Like.Juice.ORANGE, 'Test'], [1L], [Like.Juice.APPLE, 1L]] } } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/PostgresqlArraysDomainIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/array/PostgresqlArraysDomainIntegrationSpec.groovy similarity index 92% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/PostgresqlArraysDomainIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/PostgresqlArraysDomainIntegrationSpec.groovy index 678750c..3233536 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/PostgresqlArraysDomainIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/PostgresqlArraysDomainIntegrationSpec.groovy @@ -1,19 +1,20 @@ -package net.kaleidos.hibernate.array +package test.array + +import app.array.TestDouble +import app.array.TestEnum +import app.array.TestFloat +import app.array.TestInteger +import app.array.TestLong +import app.array.TestString +import app.array.TestUuid +import spock.lang.Specification +import spock.lang.Unroll import grails.gorm.transactions.Rollback import grails.testing.mixin.integration.Integration -import spock.lang.Specification -import spock.lang.Unroll -import test.array.TestDouble -import test.array.TestEnum -import test.array.TestFloat -import test.array.TestInteger -import test.array.TestLong -import test.array.TestString -import test.array.TestUuid -@Integration @Rollback +@Integration class PostgresqlArraysDomainIntegrationSpec extends Specification { def setup() { @@ -103,7 +104,7 @@ class PostgresqlArraysDomainIntegrationSpec extends Specification { testString.stringArray?.length == strings?.size() where: - strings << [null, [], ["string 1"], ["string 1", "string 2"], ["string 1", "string 2", "string 3"]] + strings << [null, [], ['string 1'], ['string 1', 'string 2'], ['string 1', 'string 2', 'string 3']] } @Unroll diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/array/UuidBuilder.groovy b/test-apps/app1/src/integration-test/groovy/test/array/UuidBuilder.groovy similarity index 75% rename from src/integration-test/groovy/net/kaleidos/hibernate/array/UuidBuilder.groovy rename to test-apps/app1/src/integration-test/groovy/test/array/UuidBuilder.groovy index b713454..f9e66ae 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/array/UuidBuilder.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/array/UuidBuilder.groovy @@ -1,5 +1,8 @@ -package net.kaleidos.hibernate.array +package test.array +import groovy.transform.CompileStatic + +@CompileStatic class UuidBuilder { static UUID createUUID(String name) { @@ -9,5 +12,4 @@ class UuidBuilder { static List createUUIDs(List names) { names.collect { createUUID(it) } } - } diff --git a/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreContainsIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreContainsIntegrationSpec.groovy new file mode 100644 index 0000000..2a0cfcc --- /dev/null +++ b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreContainsIntegrationSpec.groovy @@ -0,0 +1,115 @@ +package test.hstore + +import app.criteria.hstore.PgHstoreTestSearchService +import app.hstore.TestHstoreMap +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + +@Rollback +@Integration +class PgHstoreContainsIntegrationSpec extends Specification { + + @Autowired + PgHstoreTestSearchService pgHstoreTestSearchService + + def setup() { + TestHstoreMap.executeUpdate('delete from TestHstoreMap') + } + + void 'Test only one value result 2 different elements'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) + + then: + result.size() == 2 + result.find { it.name == 'test1' } + !result.find { it.name == 'test2' } + !result.find { it.name == 'test3' } + result.find { it.name == 'test4' } + + where: + map = [b: '1'] + } + + void 'Test two values that matches partialy with one element'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) + + then: + result.size() == 1 + !result.find { it.name == 'test1' } + !result.find { it.name == 'test2' } + !result.find { it.name == 'test3' } + result.find { it.name == 'test4' } + + where: + map = [b: '1', c: 'test'] + } + + void 'No matches with the same combination key/value'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) + + then: + result.size() == 0 + + where: + map = [b: '3'] + } + + void 'No matches with the same combination but one of the elements matches'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) + + then: + result.size() == 0 + + where: + map = [b: '1', c: 'test-otro'] + } + + void 'When empty map returns all elements'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContains', map) + + then: + result.size() == 4 + + where: + map = [:] + } +} diff --git a/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreContainsKeyIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreContainsKeyIntegrationSpec.groovy new file mode 100644 index 0000000..9e7043e --- /dev/null +++ b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreContainsKeyIntegrationSpec.groovy @@ -0,0 +1,54 @@ +package test.hstore + +import app.criteria.hstore.PgHstoreTestSearchService +import app.hstore.TestHstoreMap +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + +@Rollback +@Integration +class PgHstoreContainsKeyIntegrationSpec extends Specification { + + @Autowired + PgHstoreTestSearchService pgHstoreTestSearchService + + def setup() { + TestHstoreMap.executeUpdate('delete from TestHstoreMap') + } + + void 'Test find hstore that contains key'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '3']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContainsKey', 'b') + + then: + result.size() == 3 + result.find { it.name == 'test1' } + result.find { it.name == 'test2' } + !result.find { it.name == 'test3' } + result.find { it.name == 'test4' } + } + + void 'Test find hstore that contains other key'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '3']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreContainsKey', 'X') + + then: + result.size() == 0 + } +} diff --git a/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreILikeValueFunctionIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreILikeValueFunctionIntegrationSpec.groovy new file mode 100644 index 0000000..a2d4a04 --- /dev/null +++ b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreILikeValueFunctionIntegrationSpec.groovy @@ -0,0 +1,54 @@ +package test.hstore + +import app.criteria.hstore.PgHstoreTestSearchService +import app.hstore.TestHstoreMap +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + +@Rollback +@Integration +class PgHstoreILikeValueFunctionIntegrationSpec extends Specification { + + @Autowired + PgHstoreTestSearchService pgHstoreTestSearchService + + def setup() { + TestHstoreMap.executeUpdate('delete from TestHstoreMap') + } + + void 'Test find hstore that ilikes value'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '3']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreILikeValue', '%test%') + + then: + result.size() == 3 + result.find { it.name == 'test1' } + !result.find { it.name == 'test2' } + result.find { it.name == 'test3' } + result.find { it.name == 'test4' } + } + + void 'Test find hstore that no ilikes value'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [b: '2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test2']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'Xa', b: '3']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreILikeValue', '%X') + + then: + result.size() == 0 + } +} diff --git a/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreIsContainedIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreIsContainedIntegrationSpec.groovy new file mode 100644 index 0000000..f9c53fa --- /dev/null +++ b/test-apps/app1/src/integration-test/groovy/test/hstore/PgHstoreIsContainedIntegrationSpec.groovy @@ -0,0 +1,81 @@ +package test.hstore + +import app.criteria.hstore.PgHstoreTestSearchService +import app.hstore.TestHstoreMap +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + +@Rollback +@Integration +class PgHstoreIsContainedIntegrationSpec extends Specification { + + @Autowired + PgHstoreTestSearchService pgHstoreTestSearchService + + def setup() { + TestHstoreMap.executeUpdate('delete from TestHstoreMap') + } + + void 'No element matches with the empty set'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [d: '10']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreIsContained', map) + + then: + result.size() == 0 + + where: + map = [:] + } + + void 'All elements matches'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [d: '10']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreIsContained', map) + + then: + result.size() == 4 + result.find { it.name == 'test1' } + result.find { it.name == 'test2' } + result.find { it.name == 'test3' } + result.find { it.name == 'test4' } + + where: + map = [a: 'test', b: '1', c: 'test', d: '10'] + } + + void 'Some elements matches'() { + setup: + new TestHstoreMap(name: 'test1', testAttributes: [a: 'test', b: '1']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test2', testAttributes: [d: '10']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test3', testAttributes: [a: 'test']).save(flush: true, failOnError: true) + new TestHstoreMap(name: 'test4', testAttributes: [c: 'test', b: '1']).save(flush: true, failOnError: true) + + when: + def result = pgHstoreTestSearchService.search('testAttributes', 'pgHstoreIsContained', map) + + then: + result.size() == 3 + result.find { it.name == 'test1' } + !result.find { it.name == 'test2' } + result.find { it.name == 'test3' } + result.find { it.name == 'test4' } + + where: + map = [a: 'test', b: '1', c: 'test'] + } +} diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PostgresqlHstoreMapDomainIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/hstore/PostgresqlHstoreMapDomainIntegrationSpec.groovy similarity index 87% rename from src/integration-test/groovy/net/kaleidos/hibernate/hstore/PostgresqlHstoreMapDomainIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/hstore/PostgresqlHstoreMapDomainIntegrationSpec.groovy index 104fa90..7702efb 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/hstore/PostgresqlHstoreMapDomainIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/hstore/PostgresqlHstoreMapDomainIntegrationSpec.groovy @@ -1,14 +1,15 @@ -package net.kaleidos.hibernate.hstore +package test.hstore -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.hstore.TestHstoreMap import spock.lang.Ignore import spock.lang.Specification import spock.lang.Unroll -import test.hstore.TestHstoreMap -@Integration +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PostgresqlHstoreMapDomainIntegrationSpec extends Specification { def setup() { @@ -31,8 +32,8 @@ class PostgresqlHstoreMapDomainIntegrationSpec extends Specification { where: data | attribute | value - [foo: "bar"] | "foo" | "bar" - ["foo,bar": "baz,qux"] | "foo,bar" | "baz,qux" + [foo: 'bar'] | 'foo' | 'bar' + ['foo,bar': 'baz,qux'] | 'foo,bar' | 'baz,qux' } @Unroll @@ -51,8 +52,8 @@ class PostgresqlHstoreMapDomainIntegrationSpec extends Specification { where: data | key | value - [foo: "bar", xxx: "abc"] | "foo" | "bar" - ["foo,bar": "baz,qux"] | "foo,bar" | "baz,qux" + [foo: 'bar', xxx: 'abc'] | 'foo' | 'bar' + ['foo,bar': 'baz,qux'] | 'foo,bar' | 'baz,qux' } @Unroll @@ -71,9 +72,9 @@ class PostgresqlHstoreMapDomainIntegrationSpec extends Specification { where: data | valueToRemove | size - [foo: "bar", xxx: "abc"] | 'xxx' | 1 - ["foo,bar": "baz,qux"] | 'foo,bar' | 0 - [foo: "bar"] | 'xxx' | 1 + [foo: 'bar', xxx: 'abc'] | 'xxx' | 1 + ['foo,bar': 'baz,qux'] | 'foo,bar' | 0 + [foo: 'bar'] | 'xxx' | 1 } @Unroll @@ -95,8 +96,8 @@ class PostgresqlHstoreMapDomainIntegrationSpec extends Specification { where: data | attribute | value - [foo: "bar"] | "foo" | "bar" - ["foo,bar": "baz,qux"] | "foo,bar" | "baz,qux" + [foo: 'bar'] | 'foo' | 'bar' + ['foo,bar': 'baz,qux'] | 'foo,bar' | 'baz,qux' } @Unroll @@ -137,5 +138,4 @@ class PostgresqlHstoreMapDomainIntegrationSpec extends Specification { then: 'It should be dirty' retrievedTestHstoreMap.isDirty() } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonEqualsIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonEqualsIntegrationSpec.groovy similarity index 86% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonEqualsIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonEqualsIntegrationSpec.groovy index 6999824..8b2cf62 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonEqualsIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonEqualsIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.json.PgJsonTestSearchService +import app.json.TestMapJson import spock.lang.Specification import spock.lang.Unroll -import test.criteria.json.PgJsonTestSearchService -import test.json.TestMapJson -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgJsonEqualsIntegrationSpec extends Specification { - @Autowired PgJsonTestSearchService pgJsonTestSearchService + @Autowired + PgJsonTestSearchService pgJsonTestSearchService def setup() { TestMapJson.executeUpdate('delete from TestMapJson') diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonPathsIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonPathsIntegrationSpec.groovy similarity index 91% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonPathsIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonPathsIntegrationSpec.groovy index 62a58ab..3ba9b3d 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonPathsIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonPathsIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.json.PgJsonTestSearchService +import app.json.TestMapJson import spock.lang.Specification import spock.lang.Unroll -import test.criteria.json.PgJsonTestSearchService -import test.json.TestMapJson -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgJsonPathsIntegrationSpec extends Specification { - @Autowired PgJsonTestSearchService pgJsonTestSearchService + @Autowired + PgJsonTestSearchService pgJsonTestSearchService @Unroll void 'Test equals finding nested values (json). sqlOp: equals'() { @@ -55,5 +58,4 @@ class PgJsonPathsIntegrationSpec extends Specification { 3 || 1 6 || 0 } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonValuesIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonValuesIntegrationSpec.groovy similarity index 93% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonValuesIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonValuesIntegrationSpec.groovy index 84253c0..0162b67 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonValuesIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonValuesIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.json.PgJsonTestSearchService +import app.json.TestMapJson import spock.lang.Specification import spock.lang.Unroll -import test.criteria.json.PgJsonTestSearchService -import test.json.TestMapJson -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgJsonValuesIntegrationSpec extends Specification { - @Autowired PgJsonTestSearchService pgJsonTestSearchService + @Autowired + PgJsonTestSearchService pgJsonTestSearchService @Unroll void 'Test equals finding value: #value with condition is ilike (json)'() { @@ -73,5 +76,4 @@ class PgJsonValuesIntegrationSpec extends Specification { 'Iván' || 1 'John' || 3 } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbContainsIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbContainsIntegrationSpec.groovy similarity index 94% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbContainsIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonbContainsIntegrationSpec.groovy index 9bde21c..0fae20d 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbContainsIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbContainsIntegrationSpec.groovy @@ -1,17 +1,20 @@ -package net.kaleidos.hibernate.json +package test.json + +import app.criteria.json.PgJsonbTestSearchService +import app.json.TestMapJsonb +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired import grails.gorm.transactions.Rollback import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.json.PgJsonbTestSearchService -import test.json.TestMapJsonb -@Integration @Rollback +@Integration class PgJsonbContainsIntegrationSpec extends Specification { - @Autowired PgJsonbTestSearchService pgJsonbTestSearchService + @Autowired + PgJsonbTestSearchService pgJsonbTestSearchService def setup() { TestMapJsonb.executeUpdate('delete from TestMapJsonb') @@ -101,5 +104,4 @@ class PgJsonbContainsIntegrationSpec extends Specification { where: map = null } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbEqualsIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbEqualsIntegrationSpec.groovy similarity index 84% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbEqualsIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonbEqualsIntegrationSpec.groovy index 17c80c1..0437c71 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbEqualsIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbEqualsIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.json.PgJsonbTestSearchService +import app.json.TestMapJsonb import spock.lang.Specification import spock.lang.Unroll -import test.criteria.json.PgJsonbTestSearchService -import test.json.TestMapJsonb -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgJsonbEqualsIntegrationSpec extends Specification { - @Autowired PgJsonbTestSearchService pgJsonbTestSearchService + @Autowired + PgJsonbTestSearchService pgJsonbTestSearchService @Unroll void 'Test equals finding value: #value (jsonb)'() { diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbIsContainedIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbIsContainedIntegrationSpec.groovy similarity index 93% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbIsContainedIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonbIsContainedIntegrationSpec.groovy index a06043c..b8fd025 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbIsContainedIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbIsContainedIntegrationSpec.groovy @@ -1,17 +1,20 @@ -package net.kaleidos.hibernate.json +package test.json + +import app.criteria.json.PgJsonbTestSearchService +import app.json.TestMapJsonb +import spock.lang.Specification + +import org.springframework.beans.factory.annotation.Autowired import grails.gorm.transactions.Rollback import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Specification -import test.criteria.json.PgJsonbTestSearchService -import test.json.TestMapJsonb -@Integration @Rollback +@Integration class PgJsonbIsContainedIntegrationSpec extends Specification { - @Autowired PgJsonbTestSearchService pgJsonbTestSearchService + @Autowired + PgJsonbTestSearchService pgJsonbTestSearchService def setup() { TestMapJsonb.executeUpdate('delete from TestMapJsonb') @@ -84,5 +87,4 @@ class PgJsonbIsContainedIntegrationSpec extends Specification { where: map = null } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbPathsIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbPathsIntegrationSpec.groovy similarity index 91% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbPathsIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonbPathsIntegrationSpec.groovy index 5549cbb..09223aa 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbPathsIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbPathsIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.json.PgJsonbTestSearchService +import app.json.TestMapJsonb import spock.lang.Specification import spock.lang.Unroll -import test.criteria.json.PgJsonbTestSearchService -import test.json.TestMapJsonb -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgJsonbPathsIntegrationSpec extends Specification { - @Autowired PgJsonbTestSearchService pgJsonbTestSearchService + @Autowired + PgJsonbTestSearchService pgJsonbTestSearchService @Unroll void 'Test equals finding nested values (jsonb). sqlOp: equals'() { @@ -55,5 +58,4 @@ class PgJsonbPathsIntegrationSpec extends Specification { 3 || 1 6 || 0 } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbValuesIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbValuesIntegrationSpec.groovy similarity index 93% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbValuesIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PgJsonbValuesIntegrationSpec.groovy index dad7b46..0623645 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PgJsonbValuesIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PgJsonbValuesIntegrationSpec.groovy @@ -1,18 +1,21 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration -import org.springframework.beans.factory.annotation.Autowired +import app.criteria.json.PgJsonbTestSearchService +import app.json.TestMapJsonb import spock.lang.Specification import spock.lang.Unroll -import test.criteria.json.PgJsonbTestSearchService -import test.json.TestMapJsonb -@Integration +import org.springframework.beans.factory.annotation.Autowired + +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PgJsonbValuesIntegrationSpec extends Specification { - @Autowired PgJsonbTestSearchService pgJsonbTestSearchService + @Autowired + PgJsonbTestSearchService pgJsonbTestSearchService @Unroll void 'Test equals finding value: #value with condition is ilike (jsonb)'() { @@ -73,5 +76,4 @@ class PgJsonbValuesIntegrationSpec extends Specification { 'Iván' || 1 'John' || 3 } - } diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PostgresqlJsonMapDomainIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PostgresqlJsonMapDomainIntegrationSpec.groovy similarity index 80% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PostgresqlJsonMapDomainIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PostgresqlJsonMapDomainIntegrationSpec.groovy index 764f9df..4265b36 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PostgresqlJsonMapDomainIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PostgresqlJsonMapDomainIntegrationSpec.groovy @@ -1,13 +1,14 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.json.TestMapJson import spock.lang.Specification import spock.lang.Unroll -import test.json.TestMapJson -@Integration +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PostgresqlJsonMapDomainIntegrationSpec extends Specification { def setup() { @@ -39,7 +40,7 @@ class PostgresqlJsonMapDomainIntegrationSpec extends Specification { void 'save and read a domain class with json'() { setup: - def value = [name: 'Ivan', age: 34, hasChilds: true, childs: [[name: 'Judith', age: 7], [name: 'Adriana', age: 4]]] + def value = [name: 'Ivan', age: 34, hasChildren: true, children: [[name: 'Judith', age: 7], [name: 'Adriana', age: 4]]] def testMapJson = new TestMapJson(data: value) when: @@ -50,7 +51,7 @@ class PostgresqlJsonMapDomainIntegrationSpec extends Specification { and: def obj = testMapJson.get(testMapJson.id) - obj.data.keySet().collect { it.toString() }.equals(['name', 'age', 'hasChilds', 'childs']) - obj.data.childs.size() == 2 + obj.data.keySet().collect { it.toString() } == ['name', 'age', 'hasChildren', 'children'] + obj.data.children.size() == 2 } } \ No newline at end of file diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/json/PostgresqlJsonbMapDomainIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/json/PostgresqlJsonbMapDomainIntegrationSpec.groovy similarity index 96% rename from src/integration-test/groovy/net/kaleidos/hibernate/json/PostgresqlJsonbMapDomainIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/json/PostgresqlJsonbMapDomainIntegrationSpec.groovy index ceafe9e..c072ee8 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/json/PostgresqlJsonbMapDomainIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/json/PostgresqlJsonbMapDomainIntegrationSpec.groovy @@ -1,13 +1,14 @@ -package net.kaleidos.hibernate.json +package test.json -import grails.gorm.transactions.Rollback -import grails.testing.mixin.integration.Integration +import app.json.TestMapJsonb import spock.lang.Specification import spock.lang.Unroll -import test.json.TestMapJsonb -@Integration +import grails.gorm.transactions.Rollback +import grails.testing.mixin.integration.Integration + @Rollback +@Integration class PostgresqlJsonbMapDomainIntegrationSpec extends Specification { def setup() { diff --git a/src/integration-test/groovy/net/kaleidos/hibernate/order/PgOrderIntegrationSpec.groovy b/test-apps/app1/src/integration-test/groovy/test/order/PgOrderIntegrationSpec.groovy similarity index 91% rename from src/integration-test/groovy/net/kaleidos/hibernate/order/PgOrderIntegrationSpec.groovy rename to test-apps/app1/src/integration-test/groovy/test/order/PgOrderIntegrationSpec.groovy index bcaa9f2..d1d9798 100644 --- a/src/integration-test/groovy/net/kaleidos/hibernate/order/PgOrderIntegrationSpec.groovy +++ b/test-apps/app1/src/integration-test/groovy/test/order/PgOrderIntegrationSpec.groovy @@ -1,12 +1,13 @@ -package net.kaleidos.hibernate.order +package test.order + +import app.json.TestMapJsonb +import spock.lang.Specification import grails.gorm.transactions.Rollback import grails.testing.mixin.integration.Integration -import spock.lang.Specification -import test.json.TestMapJsonb -@Integration @Rollback +@Integration class PgOrderIntegrationSpec extends Specification { def pgOrderService @@ -25,7 +26,7 @@ class PgOrderIntegrationSpec extends Specification { def result = pgOrderService.orderByJson() then: - result != null + result result.data.name == ['Iván', 'Ernesto', 'Alonso'] } @@ -39,7 +40,7 @@ class PgOrderIntegrationSpec extends Specification { def result = pgOrderService.orderByRandom() then: - result != null + result result.size() == 3 } } \ No newline at end of file diff --git a/travis-build.sh b/travis-build.sh deleted file mode 100755 index 7facd50..0000000 --- a/travis-build.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -set -e -./gradlew clean check assemble --stacktrace - -EXIT_STATUS=0 -echo "Publishing archives for branch $TRAVIS_BRANCH" -if [[ -n $TRAVIS_TAG ]] || [[ $TRAVIS_BRANCH == 'master' && $TRAVIS_PULL_REQUEST == 'false' ]]; then - if [[ -n $TRAVIS_TAG ]]; then - echo "Pushing build to Bintray" - ./gradlew bintrayUpload || EXIT_STATUS=$? - fi -fi -exit $EXIT_STATUS -