From 0d0b0525ee77126930e32291bb0168451e10e199 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 14:05:28 -0500 Subject: [PATCH 01/22] Real-development-mode ready versions of pom and CI scripts --- .circleci/config.yml | 77 +++++++++++++++++++++++++++++++++++++ .circleci/mvn-settings.xml | 9 +++++ .github/workflows/maven.yml | 37 ------------------ pom.xml | 29 ++++++++++++-- 4 files changed, 111 insertions(+), 41 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .circleci/mvn-settings.xml delete mode 100644 .github/workflows/maven.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..7c158891 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,77 @@ +version: 2.1 + +executors: + java17: + docker: + - image: 'cimg/openjdk:17.0' + resource_class: small + +orbs: + slack: circleci/slack@4.10.1 + +commands: + run_maven: + parameters: + maven_subcommand: + default: test + type: string + steps: + - checkout + - restore_cache: + keys: + - v1-dependencies-{{ checksum "pom.xml" }} + - run: + name: Run Maven + command: | + mvn -s .circleci/mvn-settings.xml << parameters.maven_subcommand >> + - run: + name: Save test results + command: | + mkdir -p ~/test-results/junit/ + find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} ~/test-results/junit/ \; + when: always + - store_test_results: + path: ~/test-results + - save_cache: + paths: + - ~/.m2 + key: v1-dependencies-{{ checksum "pom.xml" }} + +jobs: + mvn_test: + executor: java17 + steps: + - run_maven: + maven_subcommand: test + - slack/notify: + event: fail + + mvn_deploy: + executor: java17 + steps: + - run_maven: + maven_subcommand: deploy + - slack/notify: + event: always + +workflows: + test_only: + jobs: + - mvn_test: + context: [ qqq-maven-registry-credentials, kingsrook-slack ] + filters: + branches: + ignore: /dev/ + tags: + ignore: /version-.*/ + + deploy: + jobs: + - mvn_deploy: + context: [ qqq-maven-registry-credentials, kingsrook-slack ] + filters: + branches: + only: /dev/ + tags: + only: /version-.*/ + diff --git a/.circleci/mvn-settings.xml b/.circleci/mvn-settings.xml new file mode 100644 index 00000000..b2a345f0 --- /dev/null +++ b/.circleci/mvn-settings.xml @@ -0,0 +1,9 @@ + + + + github-qqq-maven-registry + ${env.QQQ_MAVEN_REGISTRY_USERNAME} + ${env.QQQ_MAVEN_REGISTRY_PASSWORD} + + + diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index 8c794698..00000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,37 +0,0 @@ -# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Java CI with Maven - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - workflow_dispatch: - branches: [ main ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 17 - uses: actions/setup-java@v2 - with: - java-version: '17' - distribution: 'adopt' - cache: maven - - name: maven-settings-xml-action - uses: whelk-io/maven-settings-xml-action@v20 - with: - repositories: '[{ "id": "github-qqq-maven-registry", "url": "https://maven.pkg.github.com/Kingsrook/qqq-maven-registry", "snapshots": { "enabled": "true" }}]' - servers: '[{ "id": "github-qqq-maven-registry", "username": "${{ secrets.QQQ_MAVEN_REGISTRY_USERNAME }}", "password": "${{ secrets.QQQ_MAVEN_REGISTRY_PASSWORD }}" }]' - - name: Build with Maven - run: mvn -B package --file pom.xml - - name: Publish to GitHub Packages Apache Maven - run: mvn deploy - env: - GITHUB_TOKEN: ${{ github.token }} diff --git a/pom.xml b/pom.xml index f6555ab6..33f3c557 100644 --- a/pom.xml +++ b/pom.xml @@ -20,14 +20,18 @@ ~ along with this program. If not, see . --> - + 4.0.0 com.kingsrook.qqq qqq-backend-module-rdbms - 0.0-SNAPSHOT + 0.0.0-SNAPSHOT + + + scm:git:git@github.com:Kingsrook/qqq-backend-module-rdbms.git + scm:git:git@github.com:Kingsrook/qqq-backend-module-rdbms.git + HEAD + @@ -138,6 +142,23 @@ + + com.amashchenko.maven.plugin + gitflow-maven-plugin + 1.18.0 + + + main + dev + version- + + true + install + true + 1 + + + From d96039f0b875e11359006f7986c62a894e42104f Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 14:08:28 -0500 Subject: [PATCH 02/22] Update qqq-backend-core to 0.0.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33f3c557..1cb8d192 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.kingsrook.qqq qqq-backend-core - 0.0-SNAPSHOT + 0.0.0-SNAPSHOT From cb92104f6093d10e0f04ad581e81e3225e9c1f7e Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 14:39:52 -0500 Subject: [PATCH 03/22] Fixed id on repository --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1cb8d192..ce7ca9db 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ - github + github-qqq-maven-registry GitHub QQQ Maven Registry https://maven.pkg.github.com/Kingsrook/qqq-maven-registry From 1c82752346aed118acf079ae46d0b647587bdef7 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 14:40:02 -0500 Subject: [PATCH 04/22] Change to -- comments in copyright --- src/test/resources/prime-test-database.sql | 40 +++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/test/resources/prime-test-database.sql b/src/test/resources/prime-test-database.sql index b314c28a..07bb1dd6 100644 --- a/src/test/resources/prime-test-database.sql +++ b/src/test/resources/prime-test-database.sql @@ -1,23 +1,23 @@ -/* - * QQQ - Low-code Application Framework for Engineers. - * Copyright (C) 2021-2022. Kingsrook, LLC - * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States - * contact@kingsrook.com - * https://github.com/Kingsrook/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ +-- +-- QQQ - Low-code Application Framework for Engineers. +-- Copyright (C) 2021-2022. Kingsrook, LLC +-- 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States +-- contact@kingsrook.com +-- https://github.com/Kingsrook/ +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU Affero General Public License as +-- published by the Free Software Foundation, either version 3 of the +-- License, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Affero General Public License for more details. +-- +-- You should have received a copy of the GNU Affero General Public License +-- along with this program. If not, see . +-- DROP TABLE IF EXISTS person; CREATE TABLE person From 90dcea65ce5cf0889d5560615c24686aac0ae615 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 14:40:15 -0500 Subject: [PATCH 05/22] Update to strip away comment lines (e.g., copyright) --- .../qqq/backend/module/rdbms/actions/RDBMSActionTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSActionTest.java b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSActionTest.java index 2964835c..defb2025 100644 --- a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSActionTest.java @@ -105,6 +105,7 @@ public class RDBMSActionTest InputStream primeTestDatabaseSqlStream = RDBMSActionTest.class.getResourceAsStream("/prime-test-database.sql"); assertNotNull(primeTestDatabaseSqlStream); List lines = (List) IOUtils.readLines(primeTestDatabaseSqlStream); + lines = lines.stream().filter(line -> !line.startsWith("-- ")).toList(); String joinedSQL = String.join("\n", lines); for(String sql : joinedSQL.split(";")) { From 5b26b5c9398dcf23af076c55e77bf08efa3d34a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 19:54:52 +0000 Subject: [PATCH 06/22] Bump log4j-core from 2.15.0 to 2.17.1 Bumps log4j-core from 2.15.0 to 2.17.1. --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ce7ca9db..adbc77cc 100644 --- a/pom.xml +++ b/pom.xml @@ -81,7 +81,7 @@ org.apache.logging.log4j log4j-core - 2.15.0 + 2.17.1 org.junit.jupiter From e60aeedf589cbd412aa2d9b6ea82138341047e98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 20:13:08 +0000 Subject: [PATCH 07/22] Bump h2 from 1.4.197 to 2.1.210 Bumps [h2](https://github.com/h2database/h2database) from 1.4.197 to 2.1.210. - [Release notes](https://github.com/h2database/h2database/releases) - [Commits](https://github.com/h2database/h2database/compare/version-1.4.197...version-2.1.210) --- updated-dependencies: - dependency-name: com.h2database:h2 dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index adbc77cc..f0fe0416 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ com.h2database h2 - 1.4.197 + 2.1.210 test From 3055dd215164f79652678b2ad2d0a76ba2713788 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 15:15:43 -0500 Subject: [PATCH 08/22] Replace SERIAL with INT AUTO_INCREMENT (SERIAL stopped working in this h2 update?) --- src/test/resources/prime-test-database.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/prime-test-database.sql b/src/test/resources/prime-test-database.sql index 07bb1dd6..d95d660b 100644 --- a/src/test/resources/prime-test-database.sql +++ b/src/test/resources/prime-test-database.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS person; CREATE TABLE person ( - id SERIAL, + id INT AUTO_INCREMENT, create_date TIMESTAMP DEFAULT now(), modify_date TIMESTAMP DEFAULT now(), From fbe12575b0312a9ec96ddeb4fe7e87dc0f77cf0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jun 2022 20:18:07 +0000 Subject: [PATCH 09/22] Bump log4j-api from 2.15.0 to 2.17.1 Bumps log4j-api from 2.15.0 to 2.17.1. --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f0fe0416..303a4e1a 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ org.apache.logging.log4j log4j-api - 2.15.0 + 2.17.1 org.apache.logging.log4j From 1ce6027dc8d1e9afbda36b76d377f6570aa78cfd Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 13 Jun 2022 15:50:38 -0500 Subject: [PATCH 10/22] Fixed github link in License --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index f64a1d0c..36d0831b 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ This is a backend-module for the qqq framework - specifically, one that works wi QQQ - Low-code Application Framework for Engineers. \ Copyright (C) 2022. Kingsrook, LLC \ 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States \ -contact@kingsrook.com -https://github.com/Kingsrook/intellij-commentator-plugin +contact@kingsrook.com | https://github.com/Kingsrook/ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as From 83c6e8eb3fb296e9a0b0e967bd44b938c6f6fa44 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Mon, 20 Jun 2022 08:36:58 -0500 Subject: [PATCH 11/22] QQQ-14 updates to meta-data and other refactoring in qqq-backend-core --- checkstyle.xml | 4 +- pom.xml | 6 + .../module/rdbms/RDBMSBackendModule.java | 38 +++ .../rdbms/actions/AbstractRDBMSAction.java | 20 ++ .../rdbms/actions/RDBMSDeleteAction.java | 6 +- .../rdbms/actions/RDBMSInsertAction.java | 6 +- .../rdbms/actions/RDBMSQueryAction.java | 6 +- .../rdbms/actions/RDBMSUpdateAction.java | 6 +- .../module/rdbms/jdbc/ConnectionManager.java | 2 +- .../model/metadata/RDBMSBackendMetaData.java | 255 ++++++++++++++++++ .../metadata/RDBMSTableBackendDetails.java} | 65 ++--- .../qqq/backend/module/rdbms/TestUtils.java | 89 ++++++ .../module/rdbms/actions/RDBMSActionTest.java | 65 +---- .../rdbms/actions/RDBMSDeleteActionTest.java | 5 +- .../rdbms/actions/RDBMSInsertActionTest.java | 5 +- .../rdbms/actions/RDBMSQueryActionTest.java | 5 +- .../rdbms/actions/RDBMSUpdateActionTest.java | 5 +- .../metadata/RDBMSBackendMetaDataTest.java | 73 +++++ 18 files changed, 535 insertions(+), 126 deletions(-) create mode 100644 src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java rename src/main/java/com/kingsrook/qqq/backend/module/rdbms/{RDBMSBackendMetaData.java => model/metadata/RDBMSTableBackendDetails.java} (59%) create mode 100644 src/test/java/com/kingsrook/qqq/backend/module/rdbms/TestUtils.java create mode 100644 src/test/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaDataTest.java diff --git a/checkstyle.xml b/checkstyle.xml index dbaa3479..76f872ed 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -46,6 +46,7 @@ --> + @@ -171,7 +172,7 @@ - + From 9faa2806faa31428b62b16c6e7d2a2e600493f86 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 23 Jun 2022 14:34:30 -0500 Subject: [PATCH 14/22] adding snapshot tags to deploy jobs --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7c158891..0ef02745 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -63,7 +63,7 @@ workflows: branches: ignore: /dev/ tags: - ignore: /version-.*/ + ignore: /(version|snapshot)-.*/ deploy: jobs: @@ -73,5 +73,5 @@ workflows: branches: only: /dev/ tags: - only: /version-.*/ + only: /(version|snapshot)-.*/ From 8758093577ce78ae13b6a363862353ff38add2ec Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 23 Jun 2022 14:37:40 -0500 Subject: [PATCH 15/22] QQQ-16 updating backend-core to 0.0.0-20220623.193535-9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e98b20e..03908b1e 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.kingsrook.qqq qqq-backend-core - 0.0.0-20220620.140542-7 + 0.0.0-20220623.193535-9 From 83786d97c37b7f1e14364402abb057039cc4e002 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 23 Jun 2022 14:39:55 -0500 Subject: [PATCH 16/22] QQQ-16 updated for changes to qqq-backend-core --- .../module/rdbms/RDBMSBackendModule.java | 2 +- .../module/rdbms/actions/RDBMSDeleteAction.java | 9 ++++----- .../module/rdbms/actions/RDBMSInsertAction.java | 17 +++++++++++------ .../module/rdbms/actions/RDBMSUpdateAction.java | 12 ++++++------ .../rdbms/actions/RDBMSDeleteActionTest.java | 7 +++---- .../rdbms/actions/RDBMSInsertActionTest.java | 6 ++---- .../rdbms/actions/RDBMSUpdateActionTest.java | 6 ++---- 7 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java index 0f6f6984..d2b00152 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java @@ -38,7 +38,7 @@ import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSTableBackendDe /******************************************************************************* - ** + ** QQQ Backend module for working with Relational Databases (RDBMS's). *******************************************************************************/ public class RDBMSBackendModule implements QBackendModuleInterface { diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java index 1c4c7ec5..64560aa2 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java @@ -31,7 +31,6 @@ import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteRequest; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteResult; import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordWithStatus; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.DeleteInterface; import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; @@ -72,14 +71,14 @@ public class RDBMSDeleteAction extends AbstractRDBMSAction implements DeleteInte Connection connection = connectionManager.getConnection((RDBMSBackendMetaData)deleteRequest.getBackend()); QueryManager.executeUpdateForRowCount(connection, sql, params); - List recordsWithStatus = new ArrayList<>(); - rs.setRecords(recordsWithStatus); + List outputRecords = new ArrayList<>(); + rs.setRecords(outputRecords); for(Serializable primaryKey : deleteRequest.getPrimaryKeys()) { QRecord qRecord = new QRecord().withTableName(deleteRequest.getTableName()).withValue("id", primaryKey); // todo uh, identify any errors? - QRecordWithStatus recordWithStatus = new QRecordWithStatus(qRecord); - recordsWithStatus.add(recordWithStatus); + QRecord outputRecord = new QRecord(qRecord); + outputRecords.add(outputRecord); } return rs; diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java index 55b0885c..e8408aef 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java @@ -30,10 +30,10 @@ import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertRequest; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertResult; import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordWithStatus; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface; +import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; @@ -50,6 +50,11 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte *******************************************************************************/ public InsertResult execute(InsertRequest insertRequest) throws QException { + if(CollectionUtils.nullSafeIsEmpty(insertRequest.getRecords())) + { + throw (new QException("Request to insert 0 records.")); + } + try { InsertResult rs = new InsertResult(); @@ -96,15 +101,15 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte // todo - non-serial-id style tables // todo - other generated values, e.g., createDate... maybe need to re-select? List idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params); - List recordsWithStatus = new ArrayList<>(); - rs.setRecords(recordsWithStatus); + List outputRecords = new ArrayList<>(); + rs.setRecords(outputRecords); int index = 0; for(QRecord record : insertRequest.getRecords()) { Integer id = idList.get(index++); - QRecordWithStatus recordWithStatus = new QRecordWithStatus(record); - recordWithStatus.setValue(table.getPrimaryKeyField(), id); - recordsWithStatus.add(recordWithStatus); + QRecord outputRecord = new QRecord(record); + outputRecord.setValue(table.getPrimaryKeyField(), id); + outputRecords.add(outputRecord); } return rs; diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java index 43232dfa..12d48e56 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java @@ -30,7 +30,6 @@ import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest; import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult; import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordWithStatus; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.UpdateInterface; @@ -55,8 +54,8 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte UpdateResult rs = new UpdateResult(); QTableMetaData table = updateRequest.getTable(); - List recordsWithStatus = new ArrayList<>(); - rs.setRecords(recordsWithStatus); + List outputRecords = new ArrayList<>(); + rs.setRecords(outputRecords); // todo - sql batch for performance // todo - if setting a bunch of records to have the same value, a single update where id IN? @@ -82,8 +81,8 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte ConnectionManager connectionManager = new ConnectionManager(); Connection connection = connectionManager.getConnection((RDBMSBackendMetaData) updateRequest.getBackend()); - QRecordWithStatus recordWithStatus = new QRecordWithStatus(record); - recordsWithStatus.add(recordWithStatus); + QRecord outputRecord = new QRecord(record); + outputRecords.add(outputRecord); try { @@ -98,7 +97,8 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte } catch(Exception e) { - recordWithStatus.setErrors(new ArrayList<>(List.of(e))); + // todo - how to communicate errors??? outputRecord.setErrors(new ArrayList<>(List.of(e))); + throw new QException("Error executing update: " + e.getMessage(), e); } } diff --git a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteActionTest.java b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteActionTest.java index d15a0492..8547040c 100644 --- a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteActionTest.java @@ -25,7 +25,6 @@ package com.kingsrook.qqq.backend.module.rdbms.actions; import java.util.List; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteRequest; import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteResult; -import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.module.rdbms.TestUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -61,7 +60,7 @@ public class RDBMSDeleteActionTest extends RDBMSActionTest deleteRequest.setPrimaryKeys(List.of(1, 2, 3, 4, 5)); DeleteResult deleteResult = new RDBMSDeleteAction().execute(deleteRequest); assertEquals(5, deleteResult.getRecords().size(), "Unfiltered delete should return all rows"); - assertTrue(deleteResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(deleteResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT id FROM person", (rs -> assertFalse(rs.next()))); } @@ -77,7 +76,7 @@ public class RDBMSDeleteActionTest extends RDBMSActionTest deleteRequest.setPrimaryKeys(List.of(1)); DeleteResult deleteResult = new RDBMSDeleteAction().execute(deleteRequest); assertEquals(1, deleteResult.getRecords().size(), "Should delete one row"); - assertTrue(deleteResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(deleteResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT id FROM person WHERE id = 1", (rs -> assertFalse(rs.next()))); } @@ -93,7 +92,7 @@ public class RDBMSDeleteActionTest extends RDBMSActionTest deleteRequest.setPrimaryKeys(List.of(1, 3, 5)); DeleteResult deleteResult = new RDBMSDeleteAction().execute(deleteRequest); assertEquals(3, deleteResult.getRecords().size(), "Should delete one row"); - assertTrue(deleteResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(deleteResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT id FROM person", (rs -> { int rowsFound = 0; while(rs.next()) diff --git a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java index ac0b5f49..d07d6450 100644 --- a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java @@ -26,13 +26,11 @@ import java.util.List; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertRequest; import com.kingsrook.qqq.backend.core.model.actions.insert.InsertResult; import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.module.rdbms.TestUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; /******************************************************************************* @@ -68,7 +66,7 @@ public class RDBMSInsertActionTest extends RDBMSActionTest InsertResult insertResult = new RDBMSInsertAction().execute(insertRequest); assertEquals(1, insertResult.getRecords().size(), "Should return 1 row"); assertNotNull(insertResult.getRecords().get(0).getValue("id"), "Should have an id in the row"); - assertTrue(insertResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(insertResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT * FROM person WHERE last_name = 'Kirk'", (rs -> { int rowsFound = 0; while(rs.next()) @@ -105,7 +103,7 @@ public class RDBMSInsertActionTest extends RDBMSActionTest assertEquals(2, insertResult.getRecords().size(), "Should return 1 row"); assertEquals(6, insertResult.getRecords().get(0).getValue("id"), "Should have next id in the row"); assertEquals(7, insertResult.getRecords().get(1).getValue("id"), "Should have next id in the row"); - assertTrue(insertResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(insertResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT * FROM person WHERE last_name = 'Picard'", (rs -> { int rowsFound = 0; while(rs.next()) diff --git a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateActionTest.java b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateActionTest.java index be6a06a9..0cbe75a2 100644 --- a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateActionTest.java @@ -26,13 +26,11 @@ import java.util.List; import com.kingsrook.qqq.backend.core.model.actions.update.UpdateRequest; import com.kingsrook.qqq.backend.core.model.actions.update.UpdateResult; import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.module.rdbms.TestUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -70,7 +68,7 @@ public class RDBMSUpdateActionTest extends RDBMSActionTest UpdateResult updateResult = new RDBMSUpdateAction().execute(updateRequest); assertEquals(1, updateResult.getRecords().size(), "Should return 1 row"); assertEquals(2, updateResult.getRecords().get(0).getValue("id"), "Should have id=2 in the row"); - assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT * FROM person WHERE last_name = 'Kirk'", (rs -> { int rowsFound = 0; while(rs.next()) @@ -115,7 +113,7 @@ public class RDBMSUpdateActionTest extends RDBMSActionTest assertEquals(2, updateResult.getRecords().size(), "Should return 2 rows"); assertEquals(1, updateResult.getRecords().get(0).getValue("id"), "Should have expected ids in the row"); assertEquals(3, updateResult.getRecords().get(1).getValue("id"), "Should have expected ids in the row"); - assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); + // todo - add errors to QRecord? assertTrue(updateResult.getRecords().stream().noneMatch(qrs -> CollectionUtils.nullSafeHasContents(qrs.getErrors())), "There should be no errors"); runTestSql("SELECT * FROM person WHERE last_name = 'From Bewitched'", (rs -> { int rowsFound = 0; while(rs.next()) From ecd2736fe84ca80bb6235f0dcd282ea3d112cfd2 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Jun 2022 16:18:14 -0500 Subject: [PATCH 17/22] QQQ-14 feedback from code review --- pom.xml | 2 +- .../module/rdbms/RDBMSBackendModule.java | 4 ++-- .../rdbms/actions/AbstractRDBMSAction.java | 21 ++++++++++++++++++- .../rdbms/actions/RDBMSDeleteAction.java | 6 +----- .../rdbms/actions/RDBMSInsertAction.java | 6 +----- .../rdbms/actions/RDBMSQueryAction.java | 6 +----- .../rdbms/actions/RDBMSUpdateAction.java | 11 ++++------ .../model/metadata/RDBMSBackendMetaData.java | 2 +- .../qqq/backend/module/rdbms/TestUtils.java | 5 +++-- 9 files changed, 34 insertions(+), 29 deletions(-) diff --git a/pom.xml b/pom.xml index 03908b1e..7e09c774 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.kingsrook.qqq qqq-backend-core - 0.0.0-20220623.193535-9 + 0.0.0-20220624.210809-12 diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java index d2b00152..752b53c9 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/RDBMSBackendModule.java @@ -69,7 +69,7 @@ public class RDBMSBackendModule implements QBackendModuleInterface @Override public Class getTableBackendDetailsClass() { - return RDBMSTableBackendDetails.class; + return (RDBMSTableBackendDetails.class); } @@ -80,7 +80,7 @@ public class RDBMSBackendModule implements QBackendModuleInterface @Override public QueryInterface getQueryInterface() { - return new RDBMSQueryAction(); + return (new RDBMSQueryAction()); } diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java index d3c7b861..366fa44c 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java @@ -22,20 +22,27 @@ package com.kingsrook.qqq.backend.module.rdbms.actions; +import java.sql.Connection; +import java.sql.SQLException; +import com.kingsrook.qqq.backend.core.model.actions.AbstractQTableRequest; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.utils.StringUtils; +import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; +import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSTableBackendDetails; /******************************************************************************* - ** + ** Base class for all core actions in the RDBMS module. *******************************************************************************/ public abstract class AbstractRDBMSAction { /******************************************************************************* + ** Get the table name to use in the RDBMS from a QTableMetaData. ** + ** That is, table.backendDetails.tableName if set -- else, table.name *******************************************************************************/ protected String getTableName(QTableMetaData table) { @@ -52,7 +59,9 @@ public abstract class AbstractRDBMSAction /******************************************************************************* + ** Get the column name to use for a field in the RDBMS, from the fieldMetaData. ** + ** That is, field.backendName if set -- else, field.name *******************************************************************************/ protected String getColumnName(QFieldMetaData field) { @@ -63,4 +72,14 @@ public abstract class AbstractRDBMSAction return (field.getName()); } + + + /******************************************************************************* + ** Get a database connection, per the backend in the request. + *******************************************************************************/ + protected Connection getConnection(AbstractQTableRequest qTableRequest) throws SQLException + { + ConnectionManager connectionManager = new ConnectionManager(); + return connectionManager.getConnection((RDBMSBackendMetaData) qTableRequest.getBackend()); + } } diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java index 64560aa2..3495a621 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSDeleteAction.java @@ -33,9 +33,7 @@ import com.kingsrook.qqq.backend.core.model.actions.delete.DeleteResult; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.DeleteInterface; -import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; -import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; /******************************************************************************* @@ -67,9 +65,7 @@ public class RDBMSDeleteAction extends AbstractRDBMSAction implements DeleteInte // todo sql customization - can edit sql and/or param list - ConnectionManager connectionManager = new ConnectionManager(); - Connection connection = connectionManager.getConnection((RDBMSBackendMetaData)deleteRequest.getBackend()); - + Connection connection = getConnection(deleteRequest); QueryManager.executeUpdateForRowCount(connection, sql, params); List outputRecords = new ArrayList<>(); rs.setRecords(outputRecords); diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java index e8408aef..74b83a8f 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java @@ -34,9 +34,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.InsertInterface; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; -import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; -import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; /******************************************************************************* @@ -91,15 +89,13 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte // todo sql customization - can edit sql and/or param list - ConnectionManager connectionManager = new ConnectionManager(); - Connection connection = connectionManager.getConnection((RDBMSBackendMetaData) insertRequest.getBackend()); - // QueryResult rs = new QueryResult(); // List records = new ArrayList<>(); // rs.setRecords(records); // todo - non-serial-id style tables // todo - other generated values, e.g., createDate... maybe need to re-select? + Connection connection = getConnection(insertRequest); List idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params); List outputRecords = new ArrayList<>(); rs.setRecords(outputRecords); diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java index 8573a621..67837e73 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java @@ -44,9 +44,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; -import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; -import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; /******************************************************************************* @@ -97,13 +95,11 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf // todo sql customization - can edit sql and/or param list - ConnectionManager connectionManager = new ConnectionManager(); - Connection connection = connectionManager.getConnection((RDBMSBackendMetaData) queryRequest.getBackend()); - QueryResult rs = new QueryResult(); List records = new ArrayList<>(); rs.setRecords(records); + Connection connection = getConnection(queryRequest); QueryManager.executeStatement(connection, sql, ((ResultSet resultSet) -> { ResultSetMetaData metaData = resultSet.getMetaData(); diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java index 12d48e56..6bd0a720 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java @@ -33,9 +33,7 @@ import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.UpdateInterface; -import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; -import com.kingsrook.qqq.backend.module.rdbms.model.metadata.RDBMSBackendMetaData; /******************************************************************************* @@ -51,7 +49,7 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte { try { - UpdateResult rs = new UpdateResult(); + UpdateResult rs = new UpdateResult(); QTableMetaData table = updateRequest.getTable(); List outputRecords = new ArrayList<>(); @@ -59,7 +57,8 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte // todo - sql batch for performance // todo - if setting a bunch of records to have the same value, a single update where id IN? - int recordIndex = 0; + Connection connection = getConnection(updateRequest); + int recordIndex = 0; for(QRecord record : updateRequest.getRecords()) { List updateableFields = table.getFields().values().stream() @@ -78,9 +77,6 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte // todo sql customization - can edit sql and/or param list - ConnectionManager connectionManager = new ConnectionManager(); - Connection connection = connectionManager.getConnection((RDBMSBackendMetaData) updateRequest.getBackend()); - QRecord outputRecord = new QRecord(record); outputRecords.add(outputRecord); @@ -92,6 +88,7 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte params.add(record.getValue(field.getName())); } params.add(record.getValue(table.getPrimaryKeyField())); + QueryManager.executeUpdate(connection, sql.toString(), params); // todo - auto-updated values, e.g., modifyDate... maybe need to re-select? } diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java index 7aac5d44..e5fa34bb 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java @@ -27,7 +27,7 @@ import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule; /******************************************************************************* - ** + ** Meta-data to provide details of an RDBMS backend (e.g., connection params) *******************************************************************************/ public class RDBMSBackendMetaData extends QBackendMetaData { diff --git a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/TestUtils.java b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/TestUtils.java index 347bbf9e..1e9596db 100644 --- a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/TestUtils.java +++ b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/TestUtils.java @@ -72,7 +72,7 @@ public class TestUtils public static QTableMetaData defineTablePerson() { return new QTableMetaData() - .withName("a-person") + .withName("a-person") // use this name, so it isn't the same as the actual database-table name (which must come from the backend details) .withLabel("Person") .withBackendName(defineBackend().getName()) .withPrimaryKeyField("id") @@ -83,7 +83,8 @@ public class TestUtils .withField(new QFieldMetaData("lastName", QFieldType.STRING).withBackendName("last_name")) .withField(new QFieldMetaData("birthDate", QFieldType.DATE).withBackendName("birth_date")) .withField(new QFieldMetaData("email", QFieldType.STRING)) - .withBackendDetails(new RDBMSTableBackendDetails().withTableName("person")); + .withBackendDetails(new RDBMSTableBackendDetails() + .withTableName("person")); } } From b4c3c8246f051bc5916f21a10658a260e6a9e678 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Tue, 28 Jun 2022 11:21:27 -0500 Subject: [PATCH 18/22] QQQ-14 Add secret handling in meta data; update to scrub values before insert/update --- pom.xml | 2 +- .../rdbms/actions/AbstractRDBMSAction.java | 22 +++++++++++++++++++ .../rdbms/actions/RDBMSInsertAction.java | 20 ++++++++++------- .../rdbms/actions/RDBMSQueryAction.java | 5 ++++- .../rdbms/actions/RDBMSUpdateAction.java | 5 ++++- .../model/metadata/RDBMSBackendMetaData.java | 17 ++++++++++++++ 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 7e09c774..cb61d6f2 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.kingsrook.qqq qqq-backend-core - 0.0.0-20220624.210809-12 + 0.0.0-20220628.161829-14 diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java index 366fa44c..d7837ff3 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java @@ -22,10 +22,12 @@ package com.kingsrook.qqq.backend.module.rdbms.actions; +import java.io.Serializable; import java.sql.Connection; import java.sql.SQLException; import com.kingsrook.qqq.backend.core.model.actions.AbstractQTableRequest; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.module.rdbms.jdbc.ConnectionManager; @@ -82,4 +84,24 @@ public abstract class AbstractRDBMSAction ConnectionManager connectionManager = new ConnectionManager(); return connectionManager.getConnection((RDBMSBackendMetaData) qTableRequest.getBackend()); } + + + + /******************************************************************************* + ** Handle obvious problems with values - like empty string for integer should be null. + ** + *******************************************************************************/ + protected Serializable scrubValue(QFieldMetaData field, Serializable value) + { + if("".equals(value)) + { + QFieldType type = field.getType(); + if(type.equals(QFieldType.INTEGER) || type.equals(QFieldType.DECIMAL) || type.equals(QFieldType.DATE) || type.equals(QFieldType.DATE_TIME)) + { + value = null; + } + } + + return (value); + } } diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java index 74b83a8f..c55fff9f 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java @@ -22,6 +22,7 @@ package com.kingsrook.qqq.backend.module.rdbms.actions; +import java.io.Serializable; import java.sql.Connection; import java.util.ArrayList; import java.util.List; @@ -55,7 +56,7 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte try { - InsertResult rs = new InsertResult(); + InsertResult rs = new InsertResult(); QTableMetaData table = insertRequest.getTable(); List insertableFields = table.getFields().values().stream() @@ -69,9 +70,9 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte .map(x -> "?") .collect(Collectors.joining(", ")); - String tableName = getTableName(table); - StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append("(").append(columns).append(") VALUES"); - List params = new ArrayList<>(); + String tableName = getTableName(table); + StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append("(").append(columns).append(") VALUES"); + List params = new ArrayList<>(); int recordIndex = 0; for(QRecord record : insertRequest.getRecords()) @@ -83,7 +84,10 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte sql.append("(").append(questionMarks).append(")"); for(QFieldMetaData field : insertableFields) { - params.add(record.getValue(field.getName())); + Serializable value = record.getValue(field.getName()); + value = scrubValue(field, value); + + params.add(value); } } @@ -95,14 +99,14 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte // todo - non-serial-id style tables // todo - other generated values, e.g., createDate... maybe need to re-select? - Connection connection = getConnection(insertRequest); - List idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params); + Connection connection = getConnection(insertRequest); + List idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params); List outputRecords = new ArrayList<>(); rs.setRecords(outputRecords); int index = 0; for(QRecord record : insertRequest.getRecords()) { - Integer id = idList.get(index++); + Integer id = idList.get(index++); QRecord outputRecord = new QRecord(record); outputRecord.setValue(table.getPrimaryKeyField(), id); outputRecords.add(outputRecord); diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java index 67837e73..6c892ee8 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSQueryAction.java @@ -45,6 +45,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData; import com.kingsrook.qqq.backend.core.modules.interfaces.QueryInterface; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /******************************************************************************* @@ -52,6 +54,7 @@ import com.kingsrook.qqq.backend.module.rdbms.jdbc.QueryManager; *******************************************************************************/ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterface { + private static final Logger LOG = LogManager.getLogger(RDBMSQueryAction.class); /******************************************************************************* ** @@ -127,7 +130,7 @@ public class RDBMSQueryAction extends AbstractRDBMSAction implements QueryInterf } catch(Exception e) { - e.printStackTrace(); + LOG.warn("Error executing query", e); throw new QException("Error executing query", e); } } diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java index 6bd0a720..c9bdb280 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSUpdateAction.java @@ -22,6 +22,7 @@ package com.kingsrook.qqq.backend.module.rdbms.actions; +import java.io.Serializable; import java.sql.Connection; import java.util.ArrayList; import java.util.List; @@ -85,7 +86,9 @@ public class RDBMSUpdateAction extends AbstractRDBMSAction implements UpdateInte List params = new ArrayList<>(); for(QFieldMetaData field : updateableFields) { - params.add(record.getValue(field.getName())); + Serializable value = record.getValue(field.getName()); + value = scrubValue(field, value); + params.add(value); } params.add(record.getValue(table.getPrimaryKeyField())); diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java index e5fa34bb..4c5e73df 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java @@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.module.rdbms.model.metadata; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.QSecretReader; import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule; @@ -252,4 +253,20 @@ public class RDBMSBackendMetaData extends QBackendMetaData this.password = password; return (this); } + + + + /******************************************************************************* + ** Called by the QInstanceEnricher - to do backend-type-specific enrichments. + ** Original use case is: reading secrets into fields (e.g., passwords). + *******************************************************************************/ + @Override + public void enrich() + { + super.enrich(); + QSecretReader secretReader = new QSecretReader(); + username = secretReader.readSecret(username); + password = secretReader.readSecret(password); + } + } From c6c6fb3fcbaf761c61a97700256b2db1b1cafffc Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 29 Jun 2022 10:41:44 -0500 Subject: [PATCH 19/22] QQQ-14 bumping qqq-backend-core version --- pom.xml | 2 +- .../module/rdbms/model/metadata/RDBMSBackendMetaData.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index cb61d6f2..f6853c56 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.kingsrook.qqq qqq-backend-core - 0.0.0-20220628.161829-14 + 0.0.0-20220629.151616-15 diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java index 4c5e73df..627c7557 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/model/metadata/RDBMSBackendMetaData.java @@ -22,8 +22,8 @@ package com.kingsrook.qqq.backend.module.rdbms.model.metadata; +import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter; import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; -import com.kingsrook.qqq.backend.core.model.metadata.QSecretReader; import com.kingsrook.qqq.backend.module.rdbms.RDBMSBackendModule; @@ -264,9 +264,9 @@ public class RDBMSBackendMetaData extends QBackendMetaData public void enrich() { super.enrich(); - QSecretReader secretReader = new QSecretReader(); - username = secretReader.readSecret(username); - password = secretReader.readSecret(password); + QMetaDataVariableInterpreter interpreter = new QMetaDataVariableInterpreter(); + username = interpreter.interpret(username); + password = interpreter.interpret(password); } } From 6b79de525eb4d99e6d4fec6bd075ad9561eb9cec Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Wed, 29 Jun 2022 15:51:25 -0500 Subject: [PATCH 20/22] QQQ-14 update createDate, modifyDate to default to current --- .../module/rdbms/actions/AbstractRDBMSAction.java | 9 +++++++++ .../qqq/backend/module/rdbms/jdbc/QueryManager.java | 6 ++++++ .../module/rdbms/actions/RDBMSInsertActionTest.java | 1 + 3 files changed, 16 insertions(+) diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java index d7837ff3..0f1c7110 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/AbstractRDBMSAction.java @@ -25,6 +25,7 @@ package com.kingsrook.qqq.backend.module.rdbms.actions; import java.io.Serializable; import java.sql.Connection; import java.sql.SQLException; +import java.time.OffsetDateTime; import com.kingsrook.qqq.backend.core.model.actions.AbstractQTableRequest; import com.kingsrook.qqq.backend.core.model.metadata.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.QFieldType; @@ -102,6 +103,14 @@ public abstract class AbstractRDBMSAction } } + ////////////////////////////////////////////////////// + // todo - let this come from something in the field // + ////////////////////////////////////////////////////// + if(value == null && (field.getName().equals("createDate") || field.getName().equals("modifyDate"))) + { + value = OffsetDateTime.now(); + } + return (value); } } diff --git a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java index bc07bf75..6fa85207 100644 --- a/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java +++ b/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java @@ -652,6 +652,12 @@ public class QueryManager statement.setTimestamp(index, timestamp); return (1); } + else if(value instanceof OffsetDateTime) + { + Timestamp timestamp = new Timestamp(((OffsetDateTime) value).toEpochSecond() * MS_PER_SEC); + statement.setTimestamp(index, timestamp); + return (1); + } else if(value instanceof LocalDateTime) { Timestamp timestamp = new Timestamp(((LocalDateTime) value).toEpochSecond(ZoneOffset.UTC) * MS_PER_SEC); diff --git a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java index d07d6450..852d7a51 100644 --- a/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java +++ b/src/test/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertActionTest.java @@ -74,6 +74,7 @@ public class RDBMSInsertActionTest extends RDBMSActionTest rowsFound++; assertEquals(6, rs.getInt("id")); assertEquals("James", rs.getString("first_name")); + assertNotNull(rs.getString("create_date")); } assertEquals(1, rowsFound); })); From 214c36a07cdf29c6969fd10a451bfbc4f4f33eca Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 1 Jul 2022 11:18:04 -0500 Subject: [PATCH 21/22] Update qqq-backend-core to 0.0.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6853c56..93e6a322 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ com.kingsrook.qqq qqq-backend-core - 0.0.0-20220629.151616-15 + 0.0.0 From bb8d0706e23a378e06b5b1be18250b9d161bf531 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 1 Jul 2022 11:18:20 -0500 Subject: [PATCH 22/22] Update versions for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 93e6a322..af0fdebc 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ com.kingsrook.qqq qqq-backend-module-rdbms - 0.0.0-SNAPSHOT + 0.0.0 scm:git:git@github.com:Kingsrook/qqq-backend-module-rdbms.git