From 3175ce40584dbf44fd51d166028f1b14cdcdb2b8 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Wed, 27 Jan 2021 15:03:18 +0100 Subject: [PATCH] repo-sqale: modifyObject updates fullObject (not attributes yet) --- .../midpoint/schema/SchemaHelper.java | 4 + repo/repo-sqale/sql/pgnew-repo.sql | 33 ++++--- .../repo/sqale/SqaleRepositoryService.java | 99 ++++++++++++++++--- .../repo/sqale/SqaleTransformerBase.java | 8 +- .../midpoint/repo/sqale/SqaleUtils.java | 45 +++++++++ .../sqale/qmapping/NodeSqlTransformer.java | 7 +- .../sqale/qmapping/ObjectSqlTransformer.java | 32 +++--- .../repo/sqale/qmapping/QNodeMapping.java | 2 +- .../repo/sqale/qmapping/QObjectMapping.java | 5 + .../sqale/qmapping/SqaleModelMapping.java | 2 + .../evolveum/midpoint/repo/sql/AuditTest.java | 2 +- .../repo/sql/SqlAuditServiceImpl.java | 2 +- .../repo/sqlbase/SqlTransformerContext.java | 6 +- .../sqlbase/mapping/item/ItemSqlMapper.java | 2 + 14 files changed, 191 insertions(+), 58 deletions(-) create mode 100644 repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/SchemaHelper.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/SchemaHelper.java index 16f8a9a784f..6f939901f7a 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/SchemaHelper.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/SchemaHelper.java @@ -34,6 +34,10 @@ public PrismContext getPrismContext() { return prismContext; } + public RelationRegistry relationRegistry() { + return relationRegistry; + } + public GetOperationOptionsBuilder getOperationOptionsBuilder() { return new GetOperationOptionsBuilderImpl(prismContext); } diff --git a/repo/repo-sqale/sql/pgnew-repo.sql b/repo/repo-sqale/sql/pgnew-repo.sql index 2e835a0849a..46a790b187e 100644 --- a/repo/repo-sqale/sql/pgnew-repo.sql +++ b/repo/repo-sqale/sql/pgnew-repo.sql @@ -62,13 +62,14 @@ END $$; -- BEFORE UPDATE trigger - must be declared on all concrete m_object sub-tables. --- Checks that OID is not changed. -CREATE OR REPLACE FUNCTION update_object_oid() +-- Checks that OID is not changed and updates db_modified column. +CREATE OR REPLACE FUNCTION before_update_object() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF NEW.oid = OLD.oid THEN + NEW.db_modified = current_timestamp; -- must return NEW, NULL would skip the update RETURN NEW; END IF; @@ -126,6 +127,10 @@ CREATE TABLE m_object ( -- add GIN index for concrete tables where more than hundreds of entries are expected (see m_user) ext JSONB, + -- these are purely DB-managed metadata, not mapped to in midPoint + db_created TIMESTAMPTZ NOT NULL DEFAULT current_timestamp, + db_modified TIMESTAMPTZ NOT NULL DEFAULT current_timestamp, -- updated in update trigger + -- prevents inserts to this table, but not to inherited ones; this makes it "abstract" table CHECK (FALSE) NO INHERIT ); @@ -147,8 +152,8 @@ CREATE TABLE m_resource ( CREATE TRIGGER m_resource_oid_insert_tr BEFORE INSERT ON m_resource FOR EACH ROW EXECUTE PROCEDURE insert_object_oid(); -CREATE TRIGGER m_resource_oid_update_tr BEFORE UPDATE ON m_resource - FOR EACH ROW EXECUTE PROCEDURE update_object_oid(); +CREATE TRIGGER m_resource_update_tr BEFORE UPDATE ON m_resource + FOR EACH ROW EXECUTE PROCEDURE before_update_object(); CREATE TRIGGER m_resource_oid_delete_tr AFTER DELETE ON m_resource FOR EACH ROW EXECUTE PROCEDURE delete_object_oid(); @@ -210,8 +215,8 @@ CREATE TABLE m_user ( CREATE TRIGGER m_user_oid_insert_tr BEFORE INSERT ON m_user FOR EACH ROW EXECUTE PROCEDURE insert_object_oid(); -CREATE TRIGGER m_user_oid_update_tr BEFORE UPDATE ON m_user - FOR EACH ROW EXECUTE PROCEDURE update_object_oid(); +CREATE TRIGGER m_user_update_tr BEFORE UPDATE ON m_user + FOR EACH ROW EXECUTE PROCEDURE before_update_object(); CREATE TRIGGER m_user_oid_delete_tr AFTER DELETE ON m_user FOR EACH ROW EXECUTE PROCEDURE delete_object_oid(); @@ -243,8 +248,8 @@ CREATE TABLE m_shadow ( CREATE TRIGGER m_shadow_oid_insert_tr BEFORE INSERT ON m_shadow FOR EACH ROW EXECUTE PROCEDURE insert_object_oid(); -CREATE TRIGGER m_shadow_oid_update_tr BEFORE UPDATE ON m_shadow - FOR EACH ROW EXECUTE PROCEDURE update_object_oid(); +CREATE TRIGGER m_shadow_update_tr BEFORE UPDATE ON m_shadow + FOR EACH ROW EXECUTE PROCEDURE before_update_object(); CREATE TRIGGER m_shadow_oid_delete_tr AFTER DELETE ON m_shadow FOR EACH ROW EXECUTE PROCEDURE delete_object_oid(); @@ -330,8 +335,8 @@ CREATE TABLE m_acc_cert_campaign ( CREATE TRIGGER m_acc_cert_campaign_oid_insert_tr BEFORE INSERT ON m_acc_cert_campaign FOR EACH ROW EXECUTE PROCEDURE insert_object_oid(); -CREATE TRIGGER m_acc_cert_campaign_oid_update_tr BEFORE UPDATE ON m_acc_cert_campaign - FOR EACH ROW EXECUTE PROCEDURE update_object_oid(); +CREATE TRIGGER m_acc_cert_campaign_update_tr BEFORE UPDATE ON m_acc_cert_campaign + FOR EACH ROW EXECUTE PROCEDURE before_update_object(); CREATE TRIGGER m_acc_cert_campaign_oid_delete_tr AFTER DELETE ON m_acc_cert_campaign FOR EACH ROW EXECUTE PROCEDURE delete_object_oid(); @@ -392,8 +397,8 @@ CREATE TABLE m_acc_cert_definition ( CREATE TRIGGER m_acc_cert_definition_oid_insert_tr BEFORE INSERT ON m_acc_cert_definition FOR EACH ROW EXECUTE PROCEDURE insert_object_oid(); -CREATE TRIGGER m_acc_cert_definition_oid_update_tr BEFORE UPDATE ON m_acc_cert_definition - FOR EACH ROW EXECUTE PROCEDURE update_object_oid(); +CREATE TRIGGER m_acc_cert_definition_update_tr BEFORE UPDATE ON m_acc_cert_definition + FOR EACH ROW EXECUTE PROCEDURE before_update_object(); CREATE TRIGGER m_acc_cert_definition_oid_delete_tr AFTER DELETE ON m_acc_cert_definition FOR EACH ROW EXECUTE PROCEDURE delete_object_oid(); @@ -437,8 +442,8 @@ CREATE TABLE m_node ( CREATE TRIGGER m_node_oid_insert_tr BEFORE INSERT ON m_node FOR EACH ROW EXECUTE PROCEDURE insert_object_oid(); -CREATE TRIGGER m_node_oid_update_tr BEFORE UPDATE ON m_node - FOR EACH ROW EXECUTE PROCEDURE update_object_oid(); +CREATE TRIGGER m_node_update_tr BEFORE UPDATE ON m_node + FOR EACH ROW EXECUTE PROCEDURE before_update_object(); CREATE TRIGGER m_node_oid_delete_tr AFTER DELETE ON m_node FOR EACH ROW EXECUTE PROCEDURE delete_object_oid(); diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java index 78d3fffb552..fbdddc6262b 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryService.java @@ -13,6 +13,7 @@ import com.google.common.base.Strings; import com.querydsl.core.Tuple; +import com.querydsl.sql.dml.SQLUpdateClause; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,6 +25,7 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ItemDeltaCollectionsUtil; import com.evolveum.midpoint.prism.delta.PropertyDelta; +import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.repo.api.*; @@ -39,6 +41,8 @@ import com.evolveum.midpoint.schema.internals.InternalsConfig; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -57,6 +61,7 @@ public class SqaleRepositoryService implements RepositoryService { private static final String OP_NAME_PREFIX = SqaleRepositoryService.class.getSimpleName() + '.'; private final SqlRepoContext sqlRepoContext; + private final SchemaHelper schemaService; private final SqlQueryExecutor sqlQueryExecutor; private final SqlTransformerContext transformerContext; @@ -64,8 +69,9 @@ public SqaleRepositoryService( SqlRepoContext sqlRepoContext, SchemaHelper schemaService) { this.sqlRepoContext = sqlRepoContext; + this.schemaService = schemaService; this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext); - this.transformerContext = new SqlTransformerContext(schemaService); + this.transformerContext = new SqlTransformerContext(schemaService, sqlRepoContext); } @Override @@ -278,12 +284,12 @@ private , R extends MObject> String a sqlRepoContext.getMappingBySchemaType(object.getCompileTimeClass()); Q root = rootMapping.defaultAlias(); - try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { - ObjectSqlTransformer transformer = (ObjectSqlTransformer) - rootMapping.createTransformer(transformerContext, sqlRepoContext); + ObjectSqlTransformer transformer = (ObjectSqlTransformer) + rootMapping.createTransformer(transformerContext, sqlRepoContext); + R row = transformer.toRowObjectWithoutFullObject(object.asObjectable()); + try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { // first insert without full object, because we don't know the OID yet - R row = transformer.toRowObjectWithoutFullObject(object.asObjectable()); UUID oid = jdbcSession.newInsert(root) .populate(row) .executeWithKey(root.oid); @@ -355,7 +361,8 @@ public ModifyObjectResult modifyObject( if (modifications.isEmpty() && !RepoModifyOptions.isForceReindex(options)) { LOGGER.debug("Modification list is empty, nothing was modified."); - subResult.recordStatus(OperationResultStatus.SUCCESS, "Modification list is empty, nothing was modified."); + subResult.recordStatus(OperationResultStatus.SUCCESS, + "Modification list is empty, nothing was modified."); return new ModifyObjectResult<>(modifications); } @@ -372,10 +379,77 @@ public ModifyObjectResult modifyObject( logTraceModifications(modifications); try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) { - T object = readByOid(jdbcSession, type, oidUuid, null); + GetOperationOptionsBuilder getOptionsBuilder = schemaService.getOperationOptionsBuilder(); + T object = readByOid(jdbcSession, type, oidUuid, getOptionsBuilder.build()); + //noinspection unchecked + PrismObject prismObject = (PrismObject) object.asPrismObject(); + if (precondition != null && !precondition.holds(prismObject)) { + throw new PreconditionViolationException("Modification precondition does not hold for " + prismObject); + } + // invokeConflictWatchers(w -> w.beforeModifyObject(prismObject)); TODO + + PrismObject originalObject = prismObject.clone(); + + modifyObjectAttempt(jdbcSession, prismObject, modifications); + + /* + RObject rObject = objectDeltaUpdater.modifyObject(type, oid, modifications, prismObject, modifyOptions, session, attemptContext); + + LOGGER.trace("OBJECT after:\n{}", prismObject.debugDumpLazily()); + // Continuing the photo treatment: should we remove the (now obsolete) focus photo? + // We have to test prismObject at this place, because updateFullObject (below) removes photo property from the prismObject. + shouldPhotoBeRemoved = + containsFocusPhotoModification && ((FocusType) prismObject.asObjectable()).getJpegPhoto() == null; + + updateFullObject(rObject, prismObject); + + LOGGER.trace("Starting save."); + session.save(rObject); + LOGGER.trace("Save finished."); + */ + + // TODO is modifications cloning unavoidable? see the clone at the start of ObjectUpdater.modifyObjectAttempt + // If cloning will be necessary, do it at the beginning of modifyObjectAttempt, + // especially if called potentially multiple times. + return new ModifyObjectResult<>(originalObject, prismObject, modifications); } - return null; - // TODO + } + + /** + * @param schema type + * @param type of entity path + * @param row type related to the {@link Q} + */ + private , R extends MObject> + void modifyObjectAttempt( + JdbcSession jdbcSession, + PrismObject prismObject, + Collection> modifications) throws SchemaException { + + Collection> narrowedModifications = + prismObject.narrowModifications(modifications, EquivalenceStrategy.DATA, + EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS, true); + LOGGER.trace("Narrowed modifications:\n{}", DebugUtil.debugDumpLazily(narrowedModifications)); + + SqaleModelMapping rootMapping = + sqlRepoContext.getMappingBySchemaType(prismObject.getCompileTimeClass()); + Q root = rootMapping.defaultAlias(); + // TODO update will probably be replaced by some "update context" to be able to update multiple tables (+insert/delete of details) + SQLUpdateClause update = jdbcSession.newUpdate(root) + .where(root.oid.eq(UUID.fromString(prismObject.getOid()))); + + // TODO taken from "legacy" branch, how is this worse/different from ObjectDeltaUpdater.handleObjectCommonAttributes()? + ItemDeltaCollectionsUtil.applyTo(modifications, prismObject); + ObjectTypeUtil.normalizeAllRelations(prismObject, schemaService.relationRegistry()); + // TODO generate missing container IDs? is it needed? doesn't model do it? see old repo PrismIdentifierGenerator + + int newVersion = SqaleUtils.objectVersionAsInt(prismObject) + 1; + prismObject.setVersion(String.valueOf(newVersion)); + ObjectSqlTransformer transformer = (ObjectSqlTransformer) + rootMapping.createTransformer(transformerContext, sqlRepoContext); + update.set(root.fullObject, transformer.createFullObject(prismObject.asObjectable())); + update.set(root.version, newVersion); + update.execute(); } private void logTraceModifications(@NotNull Collection> modifications) { @@ -638,7 +712,7 @@ public void destroy() { /** * Handles exception outside of transaction - this does not handle transactional problems. */ - private void handleGeneralException(Throwable ex, OperationResult result) { + private void handleGeneralException(@NotNull Throwable ex, OperationResult result) { LOGGER.error("General checked exception occurred.", ex); recordException(ex, result, sqlRepoContext.getJdbcRepositoryConfiguration().isFatalException(ex)); @@ -649,9 +723,8 @@ private void handleGeneralException(Throwable ex, OperationResult result) { } private void recordException(@NotNull Throwable ex, OperationResult result, boolean fatal) { - String message = ex != null && Strings.isNullOrEmpty(ex.getMessage()) - ? ex.getMessage() : "null"; - if (Strings.isNullOrEmpty(message) && ex != null) { + String message = Strings.isNullOrEmpty(ex.getMessage()) ? ex.getMessage() : "null"; + if (Strings.isNullOrEmpty(message)) { message = ex.getMessage(); } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerBase.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerBase.java index 4eba6a44447..ec83617f88e 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerBase.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerBase.java @@ -17,7 +17,6 @@ import org.slf4j.LoggerFactory; import com.evolveum.midpoint.repo.sqlbase.SqlTransformerContext; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMapping; import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer; import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase; @@ -35,13 +34,12 @@ public abstract class SqaleTransformerBase mapping; - protected final SqlRepoContext sqlRepoContext; - protected SqaleTransformerBase(SqlTransformerContext transformerContext, - QueryModelMapping mapping, SqlRepoContext sqlRepoContext) { + protected SqaleTransformerBase( + SqlTransformerContext transformerContext, + QueryModelMapping mapping) { this.transformerContext = transformerContext; this.mapping = mapping; - this.sqlRepoContext = sqlRepoContext; } /** diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java new file mode 100644 index 00000000000..aa9b01efa1b --- /dev/null +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleUtils.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010-2021 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.repo.sqale; + +import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; + +public class SqaleUtils { + + /** + * Returns version from midPoint object as a number. + * Returns 0 for any non-number version, never returns null. + */ + public static int objectVersionAsInt(ObjectType schemaObject) { + String version = schemaObject.getVersion(); + if (version != null) { + try { + return Integer.parseInt(version); + } catch (NumberFormatException e) { + // ignorable, version will be 0 + } + } + return 0; + } + + /** + * Returns version from prism object as a number. + * Returns 0 for any non-number version, never returns null. + */ + public static int objectVersionAsInt(PrismObject prismObject) { + String version = prismObject.getVersion(); + if (version != null) { + try { + return Integer.parseInt(version); + } catch (NumberFormatException e) { + // ignorable, version will be 0 + } + } + return 0; + } +} diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/NodeSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/NodeSqlTransformer.java index 3c413e07a2c..ef581101771 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/NodeSqlTransformer.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/NodeSqlTransformer.java @@ -8,18 +8,17 @@ import org.jetbrains.annotations.NotNull; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerContext; import com.evolveum.midpoint.repo.sqale.qbean.MNode; import com.evolveum.midpoint.repo.sqale.qmodel.QNode; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; +import com.evolveum.midpoint.repo.sqlbase.SqlTransformerContext; import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; public class NodeSqlTransformer extends ObjectSqlTransformer { public NodeSqlTransformer( - SqlTransformerContext transformerContext, QNodeMapping mapping, SqlRepoContext sqlRepoContext) { - super(transformerContext, mapping, sqlRepoContext); + SqlTransformerContext transformerContext, QNodeMapping mapping) { + super(transformerContext, mapping); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/ObjectSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/ObjectSqlTransformer.java index f88b34db1f2..9a0d6178595 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/ObjectSqlTransformer.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/ObjectSqlTransformer.java @@ -19,10 +19,10 @@ import com.evolveum.midpoint.prism.SerializationOptions; import com.evolveum.midpoint.repo.sqale.MObjectTypeMapping; import com.evolveum.midpoint.repo.sqale.SqaleTransformerBase; -import com.evolveum.midpoint.repo.sqlbase.SqlTransformerContext; +import com.evolveum.midpoint.repo.sqale.SqaleUtils; import com.evolveum.midpoint.repo.sqale.qbean.MObject; import com.evolveum.midpoint.repo.sqale.qmodel.QObject; -import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext; +import com.evolveum.midpoint.repo.sqlbase.SqlTransformerContext; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -36,9 +36,10 @@ public class ObjectSqlTransformer, R extends MObject> extends SqaleTransformerBase { - public ObjectSqlTransformer(SqlTransformerContext transformerContext, - QObjectMapping mapping, SqlRepoContext sqlRepoContext) { - super(transformerContext, mapping, sqlRepoContext); + public ObjectSqlTransformer( + SqlTransformerContext transformerContext, + QObjectMapping mapping) { + super(transformerContext, mapping); } @Override @@ -116,15 +117,7 @@ public R toRowObjectWithoutFullObject(S schemaObject) { } row.lifecycleState = schemaObject.getLifecycleState(); - row.version = 0; - try { - String version = schemaObject.getVersion(); - if (version != null) { - row.version = Integer.parseInt(version); - } - } catch (NumberFormatException e) { - // ignorable, version will be 0 - } + row.version = SqaleUtils.objectVersionAsInt(schemaObject); // TODO extensions @@ -135,21 +128,26 @@ public R toRowObjectWithoutFullObject(S schemaObject) { * Serializes schema object and sets {@link R#fullObject}. */ public void setFullObject(R row, S schemaObject) throws SchemaException { + row.fullObject = createFullObject(schemaObject); + } + + public byte[] createFullObject(S schemaObject) throws SchemaException { if (schemaObject.getOid() == null) { logger.warn("Object {} going to be serialized has no assigned OID.", schemaObject); } - String serializedForm = transformerContext.serializer(sqlRepoContext) + return transformerContext.serializer() .itemsToSkip(fullObjectItemsToSkip()) .options(SerializationOptions .createSerializeReferenceNamesForNullOids() .skipIndexOnly(true) .skipTransient(true)) - .serialize(schemaObject.asPrismObject()); - row.fullObject = serializedForm.getBytes(StandardCharsets.UTF_8); + .serialize(schemaObject.asPrismObject()) + .getBytes(StandardCharsets.UTF_8); } protected Collection fullObjectItemsToSkip() { + // TODO extend later, things like FocusType.F_JPEG_PHOTO, see ObjectUpdater#updateFullObject return Collections.emptyList(); } } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QNodeMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QNodeMapping.java index e65a63535e2..8d39c73b2d9 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QNodeMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QNodeMapping.java @@ -44,7 +44,7 @@ protected QNode newAliasInstance(String alias) { @Override public NodeSqlTransformer createTransformer( SqlTransformerContext transformerContext, SqlRepoContext sqlRepoContext) { - return new NodeSqlTransformer(transformerContext, this, sqlRepoContext); + return new NodeSqlTransformer(transformerContext, this); } @Override diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QObjectMapping.java index 7b0478f518a..62b8723bde4 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QObjectMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/QObjectMapping.java @@ -37,6 +37,11 @@ protected QObjectMapping( addItemMapping(ObjectType.F_NAME, PolyStringItemFilterProcessor.mapper( path(q -> q.nameOrig), path(q -> q.nameNorm))); + + addItemMapping(ObjectType.F_METADATA, + // TODO nested-mapping + PolyStringItemFilterProcessor.mapper( + path(q -> q.nameOrig), path(q -> q.nameNorm))); // TODO mappings } diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/SqaleModelMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/SqaleModelMapping.java index 7c59ac80c8e..03372bd96a7 100644 --- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/SqaleModelMapping.java +++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmapping/SqaleModelMapping.java @@ -14,6 +14,8 @@ /** * Mapping superclass with common functions for {@link QObject} and non-objects (e.g. containers). + * + * @see QueryModelMapping */ // TODO change the type of QObject to something more abstract later (ScaleObject?) public abstract class SqaleModelMapping, R extends MObject> diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java index eb03451d261..7ec4f8cca35 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/AuditTest.java @@ -147,7 +147,7 @@ private MAuditEventRecord getAuditEventRecord(int expectedCount, int index) throws QueryException { // "create" does not actually create a new audit service, but returns the existing one SqlRepoContext sqlRepoContext = auditServiceFactory.createAuditService().getSqlRepoContext(); - SqlTransformerContext transformerContext = new SqlTransformerContext(schemaHelper); + SqlTransformerContext transformerContext = new SqlTransformerContext(schemaHelper, sqlRepoContext); SqlQueryContext context = AuditSqlQueryContext.from( AuditEventRecordType.class, transformerContext, sqlRepoContext); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index c7907afabba..4e25788fe4e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -114,7 +114,7 @@ public SqlAuditServiceImpl( this.sqlRepoContext = sqlRepoContext; this.schemaService = schemaService; this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext); - this.sqlTransformerContext = new SqlTransformerContext(schemaService); + this.sqlTransformerContext = new SqlTransformerContext(schemaService, sqlRepoContext); } public SqlRepoContext getSqlRepoContext() { diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerContext.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerContext.java index 0dddcae15fd..9b2b3a4df19 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerContext.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/SqlTransformerContext.java @@ -22,9 +22,11 @@ public class SqlTransformerContext { private final SchemaHelper schemaService; + private final SqlRepoContext sqlRepoContext; - public SqlTransformerContext(SchemaHelper schemaService) { + public SqlTransformerContext(SchemaHelper schemaService, SqlRepoContext sqlRepoContext) { this.schemaService = schemaService; + this.sqlRepoContext = sqlRepoContext; } public Class qNameToSchemaClass(QName qName) { @@ -40,7 +42,7 @@ public QName normalizeRelation(QName qName) { } @NotNull - public PrismSerializer serializer(SqlRepoContext sqlRepoContext) { + public PrismSerializer serializer() { return schemaService.createStringSerializer( sqlRepoContext.getJdbcRepositoryConfiguration().getFullObjectFormat()); } diff --git a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/item/ItemSqlMapper.java b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/item/ItemSqlMapper.java index 8620fdb629c..5adcaae0c0c 100644 --- a/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/item/ItemSqlMapper.java +++ b/repo/repo-sqlbase/src/main/java/com/evolveum/midpoint/repo/sqlbase/mapping/item/ItemSqlMapper.java @@ -51,4 +51,6 @@ public FilterProcessor createFilterProcessor( //noinspection unchecked return (FilterProcessor) filterProcessorFactory.apply(pathContext); } + + // TODO createDeltaProcessor? }