From 20a5130757b0d6acaf0ab70d78ec30feda3b6324 Mon Sep 17 00:00:00 2001 From: t-samples Date: Wed, 21 Aug 2024 09:35:33 -0500 Subject: [PATCH 1/7] CE-1546 - Moving audit ids to longs and adding general support for long ids --- .../core/actions/audits/AuditAction.java | 2 +- .../model/audits/AuditsMetaDataProvider.java | 10 ++-- .../rdbms/actions/RDBMSInsertAction.java | 6 +-- .../module/rdbms/jdbc/QueryManager.java | 50 +++++++++++++++++-- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java index 518718a9..03bb6ebe 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java @@ -272,7 +272,7 @@ public class AuditAction extends AbstractQActionFunction auditDetailRecords = new ArrayList<>(); for(AuditSingleInput auditSingleInput : CollectionUtils.nonNullList(input.getAuditSingleInputList())) { - Integer auditId = insertOutput.getRecords().get(i++).getValueInteger("id"); + Long auditId = insertOutput.getRecords().get(i++).getValueLong("id"); if(auditId == null) { LOG.warn("Missing an id for inserted audit - so won't be able to store its child details..."); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/audits/AuditsMetaDataProvider.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/audits/AuditsMetaDataProvider.java index e5aef66a..dfa09698 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/audits/AuditsMetaDataProvider.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/audits/AuditsMetaDataProvider.java @@ -176,7 +176,7 @@ public class AuditsMetaDataProvider .withRecordLabelFields("label") .withPrimaryKeyField("id") .withUniqueKey(new UniqueKey("name")) - .withField(new QFieldMetaData("id", QFieldType.INTEGER)) + .withField(new QFieldMetaData("id", QFieldType.LONG)) .withField(new QFieldMetaData("name", QFieldType.STRING)) .withField(new QFieldMetaData("label", QFieldType.STRING)) .withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME)) @@ -199,7 +199,7 @@ public class AuditsMetaDataProvider .withRecordLabelFields("name") .withPrimaryKeyField("id") .withUniqueKey(new UniqueKey("name")) - .withField(new QFieldMetaData("id", QFieldType.INTEGER)) + .withField(new QFieldMetaData("id", QFieldType.LONG)) .withField(new QFieldMetaData("name", QFieldType.STRING)) .withField(new QFieldMetaData("createDate", QFieldType.DATE_TIME)) .withField(new QFieldMetaData("modifyDate", QFieldType.DATE_TIME)) @@ -220,7 +220,7 @@ public class AuditsMetaDataProvider .withRecordLabelFormat("%s %s") .withRecordLabelFields("auditTableId", "recordId") .withPrimaryKeyField("id") - .withField(new QFieldMetaData("id", QFieldType.INTEGER)) + .withField(new QFieldMetaData("id", QFieldType.LONG)) .withField(new QFieldMetaData("auditTableId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT_TABLE)) .withField(new QFieldMetaData("auditUserId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT_USER)) .withField(new QFieldMetaData("recordId", QFieldType.INTEGER)) @@ -243,8 +243,8 @@ public class AuditsMetaDataProvider .withRecordLabelFormat("%s") .withRecordLabelFields("id") .withPrimaryKeyField("id") - .withField(new QFieldMetaData("id", QFieldType.INTEGER)) - .withField(new QFieldMetaData("auditId", QFieldType.INTEGER).withPossibleValueSourceName(TABLE_NAME_AUDIT)) + .withField(new QFieldMetaData("id", QFieldType.LONG)) + .withField(new QFieldMetaData("auditId", QFieldType.LONG).withPossibleValueSourceName(TABLE_NAME_AUDIT)) .withField(new QFieldMetaData("message", QFieldType.STRING).withMaxLength(250).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS)) .withField(new QFieldMetaData("fieldName", QFieldType.STRING).withMaxLength(100).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS)) .withField(new QFieldMetaData("oldValue", QFieldType.STRING).withMaxLength(250).withBehavior(ValueTooLongBehavior.TRUNCATE_ELLIPSIS)) diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java index b58d1386..e8488b84 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java @@ -146,8 +146,8 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte // todo sql customization - can edit sql and/or param list // 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); - int index = 0; + List idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params, table.getFields()); + int index = 0; for(QRecord record : page) { QRecord outputRecord = new QRecord(record); @@ -155,7 +155,7 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte if(CollectionUtils.nullSafeIsEmpty(record.getErrors())) { - Integer id = idList.get(index++); + Serializable id = idList.get(index++); outputRecord.setValue(table.getPrimaryKeyField(), id); } } diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java index f1e31ffe..9c345b68 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java @@ -51,8 +51,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.logging.QLogger; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PossibleValueEnum; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils; @@ -526,18 +529,57 @@ public class QueryManager /******************************************************************************* ** todo - needs (specific) unit test *******************************************************************************/ - public static List executeInsertForGeneratedIds(Connection connection, String sql, List params) throws SQLException + public static List executeInsertForGeneratedIds(Connection connection, String sql, List params, Map fields) throws SQLException { try(PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { bindParams(params.toArray(), statement); incrementStatistic(STAT_QUERIES_RAN); statement.executeUpdate(); - ResultSet generatedKeys = statement.getGeneratedKeys(); - List rs = new ArrayList<>(); + + ///////////////////////////////////////////////////////////// + // We default to idType of INTEGER but if we are passed in // + // fields attempt to find the dataType of the id field // + ///////////////////////////////////////////////////////////// + QFieldType idType = QFieldType.INTEGER; + if(fields != null && !fields.isEmpty()) + { + Optional field = fields.values().stream() + .filter(f -> f.getName().equals("id")) + .findFirst(); + + if(field.isPresent()) + { + ///////////////////////////////////////////////////////// + // if we find "id" field get the type and use it below // + ///////////////////////////////////////////////////////// + idType = field.get().getType(); + } + } + + ResultSet generatedKeys = statement.getGeneratedKeys(); + List rs = new ArrayList<>(); while(generatedKeys.next()) { - rs.add(getInteger(generatedKeys, 1)); + switch(idType) + { + case INTEGER: + { + rs.add(getInteger(generatedKeys, 1)); + break; + } + case LONG: + { + rs.add(getLong(generatedKeys, 1)); + break; + } + default: + { + LOG.warn("Unknown id data type, attempting to getInteger.", logPair("sql", sql)); + rs.add(getInteger(generatedKeys, 1)); + break; + } + } } return (rs); } From fc4e69f0597d35245668e2810e5094e0c810cb5e Mon Sep 17 00:00:00 2001 From: t-samples Date: Mon, 26 Aug 2024 12:14:01 -0500 Subject: [PATCH 2/7] CE-1546 - feedback from code review --- .../rdbms/actions/RDBMSInsertAction.java | 2 +- .../module/rdbms/jdbc/QueryManager.java | 22 ++++--------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java index e8488b84..42ac344c 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/actions/RDBMSInsertAction.java @@ -146,7 +146,7 @@ public class RDBMSInsertAction extends AbstractRDBMSAction implements InsertInte // todo sql customization - can edit sql and/or param list // 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, table.getFields()); + List idList = QueryManager.executeInsertForGeneratedIds(connection, sql.toString(), params, table.getField(table.getPrimaryKeyField()).getType()); int index = 0; for(QRecord record : page) { diff --git a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java index 9c345b68..ceed311a 100644 --- a/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java +++ b/qqq-backend-module-rdbms/src/main/java/com/kingsrook/qqq/backend/module/rdbms/jdbc/QueryManager.java @@ -51,10 +51,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import com.kingsrook.qqq.backend.core.exceptions.QException; import com.kingsrook.qqq.backend.core.logging.QLogger; -import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PossibleValueEnum; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; @@ -529,7 +527,7 @@ public class QueryManager /******************************************************************************* ** todo - needs (specific) unit test *******************************************************************************/ - public static List executeInsertForGeneratedIds(Connection connection, String sql, List params, Map fields) throws SQLException + public static List executeInsertForGeneratedIds(Connection connection, String sql, List params, QFieldType idType) throws SQLException { try(PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { @@ -538,23 +536,11 @@ public class QueryManager statement.executeUpdate(); ///////////////////////////////////////////////////////////// - // We default to idType of INTEGER but if we are passed in // - // fields attempt to find the dataType of the id field // + // We default to idType of INTEGER if it was not passed in // ///////////////////////////////////////////////////////////// - QFieldType idType = QFieldType.INTEGER; - if(fields != null && !fields.isEmpty()) + if(idType == null) { - Optional field = fields.values().stream() - .filter(f -> f.getName().equals("id")) - .findFirst(); - - if(field.isPresent()) - { - ///////////////////////////////////////////////////////// - // if we find "id" field get the type and use it below // - ///////////////////////////////////////////////////////// - idType = field.get().getType(); - } + idType = QFieldType.INTEGER; } ResultSet generatedKeys = statement.getGeneratedKeys(); From d513c8431b08b1f103f95fb7da04ee7d1093fc87 Mon Sep 17 00:00:00 2001 From: t-samples Date: Tue, 27 Aug 2024 10:01:34 -0500 Subject: [PATCH 3/7] CE-1546 - fixing the use long for id in test --- .../qqq/backend/core/actions/audits/AuditActionTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/audits/AuditActionTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/audits/AuditActionTest.java index 40b60d9d..272c7d1a 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/audits/AuditActionTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/audits/AuditActionTest.java @@ -180,7 +180,7 @@ class AuditActionTest extends BaseTest QRecord auditRecord = GeneralProcessUtils.getRecordByFieldOrElseThrow("audit", "recordId", recordId1); assertEquals("Test Audit", auditRecord.getValueString("message")); - List auditDetails = GeneralProcessUtils.getRecordListByField("auditDetail", "auditId", auditRecord.getValue("id")); + List auditDetails = GeneralProcessUtils.getRecordListByField("auditDetail", "auditId", auditRecord.getValueLong("id")); assertEquals(2, auditDetails.size()); assertThat(auditDetails).anyMatch(r -> r.getValueString("message").equals("Detail1")); assertThat(auditDetails).anyMatch(r -> r.getValueString("message").equals("Detail2")); @@ -188,13 +188,13 @@ class AuditActionTest extends BaseTest auditRecord = GeneralProcessUtils.getRecordByFieldOrElseThrow("audit", "recordId", recordId2); assertEquals("Test Another Audit", auditRecord.getValueString("message")); assertEquals(47, auditRecord.getValueInteger(TestUtils.SECURITY_KEY_TYPE_STORE)); - auditDetails = GeneralProcessUtils.getRecordListByField("auditDetail", "auditId", auditRecord.getValue("id")); + auditDetails = GeneralProcessUtils.getRecordListByField("auditDetail", "auditId", auditRecord.getValueLong("id")); assertEquals(0, auditDetails.size()); auditRecord = GeneralProcessUtils.getRecordByFieldOrElseThrow("audit", "recordId", recordId3); assertEquals("Audit 3", auditRecord.getValueString("message")); assertEquals(42, auditRecord.getValueInteger(TestUtils.SECURITY_KEY_TYPE_STORE)); - auditDetails = GeneralProcessUtils.getRecordListByField("auditDetail", "auditId", auditRecord.getValue("id")); + auditDetails = GeneralProcessUtils.getRecordListByField("auditDetail", "auditId", auditRecord.getValueLong("id")); assertEquals(1, auditDetails.size()); assertThat(auditDetails).anyMatch(r -> r.getValueString("message").equals("Detail3")); } From c3834efad38ef3fa982c0eb2b35f26505b58b778 Mon Sep 17 00:00:00 2001 From: t-samples Date: Tue, 27 Aug 2024 13:05:24 -0500 Subject: [PATCH 4/7] CE-1546 - fixing the use long for id in test --- .../implementations/memory/MemoryRecordStore.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/memory/MemoryRecordStore.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/memory/MemoryRecordStore.java index a547aaba..2fea9f9e 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/memory/MemoryRecordStore.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/modules/backend/implementations/memory/MemoryRecordStore.java @@ -373,7 +373,14 @@ public class MemoryRecordStore ///////////////////////////////////////////////// if(recordToInsert.getValue(primaryKeyField.getName()) == null && (primaryKeyField.getType().equals(QFieldType.INTEGER) || primaryKeyField.getType().equals(QFieldType.LONG))) { - recordToInsert.setValue(primaryKeyField.getName(), nextSerial++); + if(primaryKeyField.getType().equals(QFieldType.LONG)) + { + recordToInsert.setValue(primaryKeyField.getName(), (nextSerial++).longValue()); + } + else + { + recordToInsert.setValue(primaryKeyField.getName(), nextSerial++); + } } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -383,7 +390,7 @@ public class MemoryRecordStore { nextSerial = recordToInsert.getValueInteger(primaryKeyField.getName()) + 1; } - else if(primaryKeyField.getType().equals(QFieldType.LONG) && recordToInsert.getValueLong(primaryKeyField.getName()) > nextSerial) + else if(primaryKeyField.getType().equals(QFieldType.LONG) && recordToInsert.getValueInteger(primaryKeyField.getName()) > nextSerial) { ////////////////////////////////////// // todo - mmm, could overflow here? // From 4349b37c8d3220494960ace65059502b84b1e7c6 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 5 Sep 2024 07:56:20 -0500 Subject: [PATCH 5/7] Update for next development version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c6cb4676..89f4c2b0 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ - 0.22.0 + 0.23.0-SNAPSHOT UTF-8 UTF-8 From 6673a8fc4748793562cfddd7567676f7ad39944e Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 5 Sep 2024 08:45:49 -0500 Subject: [PATCH 6/7] Updating to 0.23.0 --- qqq-dev-tools/CURRENT-SNAPSHOT-VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qqq-dev-tools/CURRENT-SNAPSHOT-VERSION b/qqq-dev-tools/CURRENT-SNAPSHOT-VERSION index 21574090..ca222b7c 100644 --- a/qqq-dev-tools/CURRENT-SNAPSHOT-VERSION +++ b/qqq-dev-tools/CURRENT-SNAPSHOT-VERSION @@ -1 +1 @@ -0.22.0 +0.23.0 From 65166150e623fe76c855be539e594888d3b585bb Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Thu, 5 Sep 2024 13:28:54 -0500 Subject: [PATCH 7/7] Update versions for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89f4c2b0..fd760117 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ - 0.23.0-SNAPSHOT + 0.22.1 UTF-8 UTF-8