- All objects are identified by OID. The OID is an immutable identifier
+ All objects are identified by OID. The OID is an immutable identifier
(usually UUID). Except the OID all the objects have human-readable name.
The name is usually unique for each object type, but this is not a
strict requirement.
@@ -7486,7 +7486,7 @@
When set to true, midPoint will try to avoid adding attribute values that are already
there and remove values that are not there. Some resources do not tolerate such operations
and they respond with errors. However midPoint cannot rely on transactions. MidPoint's
- lock-free relativistic model provides the necessary consistency, occasional redundant
+ lock-free relativistic model provides the necessary consistency, occasional redundant
additions or deletions may happen. If this option is turned on then midPoint will read
the data from resource right before the operation and filter our any redundant changes.
This requires additional operation and it increases the risk of inconsistencies. However
diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java
index d72640979f9..fcca3fbefdc 100644
--- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java
+++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/performance/AbstractSchemaPerformanceTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2018 Evolveum and contributors
+ * 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.
@@ -10,18 +10,16 @@
import java.io.File;
import java.io.IOException;
-import com.evolveum.midpoint.prism.impl.match.MatchingRuleRegistryFactory;
-import com.evolveum.midpoint.prism.match.MatchingRuleRegistry;
import org.javasimon.Split;
import org.javasimon.Stopwatch;
import org.jetbrains.annotations.NotNull;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeSuite;
import org.xml.sax.SAXException;
import com.evolveum.midpoint.prism.PrismObject;
+import com.evolveum.midpoint.prism.impl.match.MatchingRuleRegistryFactory;
+import com.evolveum.midpoint.prism.match.MatchingRuleRegistry;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.MidPointPrismContextFactory;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
@@ -34,7 +32,7 @@
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
-public abstract class AbstractSchemaPerformanceTest extends AbstractUnitTest implements PerformanceTestClassMixin {
+public abstract class AbstractSchemaPerformanceTest extends AbstractUnitTest implements PerformanceTestClassMixin {
protected static final String LABEL = "new-mapxnode";
@@ -59,12 +57,6 @@ public void setup() throws SchemaException, SAXException, IOException {
assert !InternalsConfig.isConsistencyChecks();
}
- @BeforeClass
- @Override
- public void initTestMonitor() {
- PerformanceTestClassMixin.super.initTestMonitor();
- }
-
protected void measure(String label, String note, CheckedProducer> producer) throws CommonException, IOException {
measure(label, note, producer, DEFAULT_EXECUTION, DEFAULT_REPEATS);
}
@@ -102,10 +94,4 @@ protected double measureSingle(String label, CheckedProducer> producer, long e
public PrismObject getJack() throws SchemaException, IOException {
return getPrismContext().parserFor(USER_JACK_FILE).parse();
}
-
- @AfterClass
- @Override
- public void dumpReport() {
- PerformanceTestClassMixin.super.dumpReport();
- }
}
diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java
index 71a29dfc8a1..22ca341fb36 100644
--- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java
+++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2020 Evolveum and contributors
+ * 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.
@@ -7,6 +7,7 @@
package com.evolveum.midpoint.test.util;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.jetbrains.annotations.Nullable;
@@ -17,10 +18,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
-import com.evolveum.midpoint.tools.testng.MidpointTestContext;
-import com.evolveum.midpoint.tools.testng.MidpointTestMixin;
-import com.evolveum.midpoint.tools.testng.SimpleMidpointTestContext;
-import com.evolveum.midpoint.tools.testng.TestMonitor;
+import com.evolveum.midpoint.tools.testng.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
@@ -37,6 +35,7 @@ public abstract class AbstractSpringTest extends AbstractTestNGSpringContextTest
*/
protected final Trace logger = TraceManager.getTrace(getClass());
+ // region perf-test support
private TestMonitor testMonitor;
/** Called only by tests that need it, implements performance mixin interface. */
@@ -55,6 +54,40 @@ public TestMonitor testMonitor() {
return testMonitor;
}
+ // see the comment in PerformanceTestMethodMixin for explanation
+ @BeforeMethod
+ public void initTestMethodMonitor() {
+ if (this instanceof PerformanceTestMethodMixin) {
+ createTestMonitor();
+ }
+ }
+
+ // see the comment in PerformanceTestMethodMixin for explanation
+ @AfterMethod
+ public void dumpMethodReport(Method method) {
+ if (this instanceof PerformanceTestMethodMixin) {
+ ((PerformanceTestMethodMixin) this).dumpReport(
+ getClass().getSimpleName() + "#" + method.getName());
+ }
+ }
+
+ // see the comment in PerformanceTestClassMixin for explanation
+ @BeforeClass
+ public void initTestClassMonitor() {
+ if (this instanceof PerformanceTestClassMixin) {
+ createTestMonitor();
+ }
+ }
+
+ // see the comment in PerformanceTestClassMixin for explanation
+ @AfterClass
+ public void dumpClassReport() {
+ if (this instanceof PerformanceTestClassMixin) {
+ ((PerformanceTestClassMixin) this).dumpReport(getClass().getSimpleName());
+ }
+ }
+ // endregion
+
@BeforeClass
public void displayTestClassTitle() {
displayTestTitle("Starting TEST CLASS: " + getClass().getName());
@@ -91,18 +124,18 @@ public MidpointTestContext getTestContext() {
/**
* This method null all fields which are not static, final or primitive type.
- *
+ *
* All this is just to make GC work during DirtiesContext after every test class,
* because test class instances are not GCed immediately.
* If they hold autowired fields like sessionFactory (for example
* through SqlRepositoryService impl), their memory footprint is getting big.
* This can manifest as failed test initialization because of OOM in modules like model-intest.
* Strangely, this will not fail the Jenkins build (but makes it much slower).
- *
+ *
* Note that this does not work for components injected through constructor into
* final fields - if we need this cleanup, make the field non-final.
*/
- @AfterClass(alwaysRun = true)
+ @AfterClass(alwaysRun = true, dependsOnMethods = "dumpClassReport")
protected void clearClassFields() throws Exception {
logger.trace("Clearing all fields for test class {}", getClass().getName());
clearClassFields(this, getClass());
@@ -114,9 +147,7 @@ private void clearClassFields(Object object, Class> forClass) throws Exception
}
for (Field field : forClass.getDeclaredFields()) {
- // we need to skip testMonitor to have it non-null in PerformanceTestMixin#dumpReport
- if (field.getName().equals("testMonitor")
- || Modifier.isFinal(field.getModifiers())
+ if (Modifier.isFinal(field.getModifiers())
|| Modifier.isStatic(field.getModifiers())
|| field.getType().isPrimitive()) {
continue;
diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java
index dc2028284f0..5132804b409 100644
--- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java
+++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestReportUtil.java
@@ -6,14 +6,15 @@
*/
package com.evolveum.midpoint.test.util;
-import java.util.Comparator;
+import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.Format.RAW;
+import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.SortBy.NAME;
+import static com.evolveum.midpoint.schema.statistics.AbstractStatisticsPrinter.SortBy.TIME;
-import com.evolveum.midpoint.schema.statistics.OperationsPerformanceInformationUtil;
+import com.evolveum.midpoint.schema.statistics.*;
import com.evolveum.midpoint.tools.testng.TestMonitor;
import com.evolveum.midpoint.tools.testng.TestReportSection;
import com.evolveum.midpoint.util.statistics.OperationsPerformanceMonitor;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationsPerformanceInformationType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.SingleOperationPerformanceInformationType;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
public class TestReportUtil {
@@ -25,37 +26,84 @@ public static void reportGlobalPerfData(TestMonitor testMonitor) {
OperationsPerformanceInformationType performanceInformation =
OperationsPerformanceInformationUtil.toOperationsPerformanceInformationType(
OperationsPerformanceMonitor.INSTANCE.getGlobalPerformanceInformation());
- TestReportSection section = testMonitor.addReportSection("globalPerformanceInformation")
- .withColumns("Operation", "Count", "Total time (ms)", "Min", "Max", "Avg");
-
- performanceInformation.getOperation().stream()
- .sorted(Comparator.comparing(SingleOperationPerformanceInformationType::getTotalTime).reversed())
- .forEach(op -> {
- int count = zeroIfNull(op.getInvocationCount());
- float totalTime = zeroIfNull(op.getTotalTime()) / 1000.0f;
- section.addRow(
- op.getName(),
- count,
- totalTime,
- zeroIfNull(op.getMinTime()) / 1000.0f,
- zeroIfNull(op.getMaxTime()) / 1000.0f,
- avg(totalTime, count));
- });
- // TODO: How to adapt this to the code above? See OperationsPerformanceInformationPrinter for the details.
-// OperationsPerformanceInformationUtil.format(performanceInformation,
-// new AbstractStatisticsPrinter.Options(CSV, TIME), null, null));
+
+ OperationsPerformanceInformationPrinter printer = new OperationsPerformanceInformationPrinter(performanceInformation,
+ new AbstractStatisticsPrinter.Options(RAW, TIME), null, null, false);
+
+ addPrinterData(testMonitor, "globalPerformanceInformation", printer);
}
- // TODO: cleanup! taken from AbstractStatisticsPrinter
- private static int zeroIfNull(Integer n) {
- return n != null ? n : 0;
+ private static void addPrinterData(TestMonitor testMonitor, String sectionName, AbstractStatisticsPrinter> printer) {
+ printer.prepare();
+ Data data = printer.getData();
+ Formatting formatting = printer.getFormatting();
+
+ TestReportSection section = testMonitor.addReportSection(sectionName)
+ .withColumns(formatting.getColumnLabels().toArray(new String[0]));
+ data.getRawDataStream().forEach(section::addRow);
}
- private static long zeroIfNull(Long n) {
- return n != null ? n : 0;
+ /**
+ * Adds operation performance for a given task to the {@link TestMonitor}.
+ */
+ public static void reportTaskOperationPerformance(TestMonitor testMonitor, String label,
+ TaskType task, Integer iterations, Integer seconds) {
+ OperationsPerformanceInformationType performanceInformationFromTask =
+ task.getOperationStats() != null ? task.getOperationStats().getOperationsPerformanceInformation() : null;
+ OperationsPerformanceInformationType performanceInformation = performanceInformationFromTask != null ?
+ performanceInformationFromTask : new OperationsPerformanceInformationType();
+
+ OperationsPerformanceInformationPrinter printer = new OperationsPerformanceInformationPrinter(performanceInformation,
+ new AbstractStatisticsPrinter.Options(RAW, TIME), iterations, seconds, false);
+
+ addPrinterData(testMonitor, label + ":operationPerformance", printer);
}
- private static Number avg(Number total, int count) {
- return total != null && count > 0 ? total.floatValue() / count : null;
+ /**
+ * Adds repository performance for a given task to the {@link TestMonitor}.
+ */
+ public static void reportTaskRepositoryPerformance(TestMonitor testMonitor, String label,
+ TaskType task, Integer iterations, Integer seconds) {
+ RepositoryPerformanceInformationType performanceInformationFromTask =
+ task.getOperationStats() != null ? task.getOperationStats().getRepositoryPerformanceInformation() : null;
+ RepositoryPerformanceInformationType performanceInformation = performanceInformationFromTask != null ?
+ performanceInformationFromTask : new RepositoryPerformanceInformationType();
+
+ RepositoryPerformanceInformationPrinter printer = new RepositoryPerformanceInformationPrinter(performanceInformation,
+ new AbstractStatisticsPrinter.Options(RAW, NAME), iterations, seconds);
+
+ addPrinterData(testMonitor, label + ":repositoryPerformance", printer);
+ }
+
+ /**
+ * Adds caches performance for a given task to the {@link TestMonitor}.
+ */
+ public static void reportTaskCachesPerformance(TestMonitor testMonitor, String label, TaskType task) {
+ CachesPerformanceInformationType performanceInformationFromTask =
+ task.getOperationStats() != null ? task.getOperationStats().getCachesPerformanceInformation() : null;
+ CachesPerformanceInformationType performanceInformation = performanceInformationFromTask != null ?
+ performanceInformationFromTask : new CachesPerformanceInformationType();
+
+ CachePerformanceInformationPrinter printer = new CachePerformanceInformationPrinter(performanceInformation,
+ new AbstractStatisticsPrinter.Options(RAW, NAME));
+
+ addPrinterData(testMonitor, label + ":cachePerformance", printer);
+ }
+
+ /**
+ * Adds provisioning operations statistics for a given task to the {@link TestMonitor}.
+ */
+ public static void reportTaskProvisioningStatistics(TestMonitor testMonitor, String label, TaskType task) {
+ EnvironmentalPerformanceInformationType envPerformanceInformationFromTask =
+ task.getOperationStats() != null ? task.getOperationStats().getEnvironmentalPerformanceInformation() : null;
+ ProvisioningStatisticsType provisioningStatisticsFromTask = envPerformanceInformationFromTask != null ?
+ envPerformanceInformationFromTask.getProvisioningStatistics() : null;
+ ProvisioningStatisticsType provisioningStatistics = provisioningStatisticsFromTask != null ?
+ provisioningStatisticsFromTask : new ProvisioningStatisticsType();
+
+ ProvisioningStatisticsPrinter printer = new ProvisioningStatisticsPrinter(provisioningStatistics,
+ new AbstractStatisticsPrinter.Options(RAW, NAME));
+
+ addPrinterData(testMonitor, label + ":provisioningStatistics", printer);
}
}
diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java
index e23743dec49..adbbdaa0f7d 100644
--- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java
+++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java
@@ -269,7 +269,7 @@ protected DummyResourceContoller initDummyResource(String name, File resourceFil
return dummyResourceCollection.initDummyResource(name, resourceFile, resourceOid, controllerInitLambda, task, result);
}
- protected DummyResourceContoller initDummyResource(DummyTestResource resource, Task task, OperationResult result) throws Exception {
+ public DummyResourceContoller initDummyResource(DummyTestResource resource, Task task, OperationResult result) throws Exception {
resource.controller = dummyResourceCollection.initDummyResource(resource.name, resource.file, resource.oid,
resource.controllerInitLambda, task, result);
return resource.controller;
diff --git a/pom.xml b/pom.xml
index 298af2c8cf3..1931e566461 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,9 +54,17 @@
mvn clean install -P -dist -DskipTests -DskipStoryTests=false
See "extratest" profile in testing/pom.xml for all individual properties enabling extra tests.
+ Running a single IT test class from story tests with remote debugger:
+ mvn integration-test -DskipStoryTests=false -DredirectTestOutputToFile=false \
+ -Dmaven.failsafe.debug="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" \
+ -pl testing/story -Dit.test=TestSystemPerformance
+ Note the "maven.failsafe.debug", it is possible to use "maven.surefire.debug" (with -Dtest) too.
+ Change to "suspend=y" for the test to wait for the debugger (e.g. debugging the startup).
+ See: https://maven.apache.org/surefire/maven-surefire-plugin/examples/debugging.html
+ and https://maven.apache.org/surefire/maven-failsafe-plugin/examples/debugging.html
+
Running unit+IT tests of a selected module (-pl) with output to stdout:
mvn clean install -DredirectTestOutputToFile=false -pl model/model-intest
-
-->
diff --git a/repo/repo-sqale/sql/pgnew-repo.sql b/repo/repo-sqale/sql/pgnew-repo.sql
index 1e11f1f6dff..07f468f6c68 100644
--- a/repo/repo-sqale/sql/pgnew-repo.sql
+++ b/repo/repo-sqale/sql/pgnew-repo.sql
@@ -187,7 +187,7 @@ $$;
-- URI can be anything, for QNames the format is based on QNameUtil ("prefix-url#localPart").
CREATE TABLE m_uri (
id SERIAL NOT NULL PRIMARY KEY,
- uri TEXT/*VARCHAR(255)*/ NOT NULL UNIQUE
+ uri TEXT NOT NULL UNIQUE
);
-- There can be more constants pre-filled, but that adds overhead, let the first-start do it.
@@ -215,13 +215,13 @@ CREATE TABLE m_object (
oid UUID NOT NULL,
-- objectType will be overridden with GENERATED value in concrete table
objectType ObjectType NOT NULL,
- name_orig TEXT/*VARCHAR(255)*/ NOT NULL,
- name_norm TEXT/*VARCHAR(255)*/ NOT NULL,
+ name_orig TEXT NOT NULL,
+ name_norm TEXT NOT NULL,
fullObject BYTEA,
tenantRef_targetOid UUID,
tenantRef_targetType ObjectType,
tenantRef_relation_id INTEGER REFERENCES m_uri(id),
- lifecycleState TEXT/*VARCHAR(255)*/, -- TODO what is this? how many distinct values?
+ lifecycleState TEXT, -- TODO what is this? how many distinct values?
cid_seq BIGINT NOT NULL DEFAULT 1, -- sequence for container id, next free cid
version INTEGER NOT NULL DEFAULT 1,
-- complex DB columns, add indexes as needed per concrete table, e.g. see m_user
@@ -366,15 +366,15 @@ CREATE INDEX m_ref_role_member_targetOid_relation_id_idx
CREATE TABLE m_focus (
-- will be overridden with GENERATED value in concrete table
objectType ObjectType NOT NULL,
- costCenter TEXT/*VARCHAR(255)*/,
- emailAddress TEXT/*VARCHAR(255)*/,
+ costCenter TEXT,
+ emailAddress TEXT,
photo BYTEA, -- will be TOAST-ed if necessary
- locale TEXT/*VARCHAR(255)*/,
- locality_orig TEXT/*VARCHAR(255)*/,
- locality_norm TEXT/*VARCHAR(255)*/,
- preferredLanguage TEXT/*VARCHAR(255)*/,
- telephoneNumber TEXT/*VARCHAR(255)*/,
- timezone TEXT/*VARCHAR(255)*/,
+ locale TEXT,
+ locality_orig TEXT,
+ locality_norm TEXT,
+ preferredLanguage TEXT,
+ telephoneNumber TEXT,
+ timezone TEXT,
-- credential/password/metadata
passwordCreateTimestamp TIMESTAMPTZ,
passwordModifyTimestamp TIMESTAMPTZ,
@@ -383,7 +383,7 @@ CREATE TABLE m_focus (
effectiveStatus ActivationStatusType,
enableTimestamp TIMESTAMPTZ,
disableTimestamp TIMESTAMPTZ,
- disableReason TEXT/*VARCHAR(255)*/,
+ disableReason TEXT,
validityStatus TimeIntervalStatusType,
validFrom TIMESTAMPTZ,
validTo TIMESTAMPTZ,
@@ -445,23 +445,23 @@ ALTER TABLE m_generic_object ADD CONSTRAINT m_generic_object_name_norm_key UNIQU
CREATE TABLE m_user (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('USER') STORED,
- additionalName_orig TEXT/*VARCHAR(255)*/,
- additionalName_norm TEXT/*VARCHAR(255)*/,
- employeeNumber TEXT/*VARCHAR(255)*/,
- familyName_orig TEXT/*VARCHAR(255)*/,
- familyName_norm TEXT/*VARCHAR(255)*/,
- fullName_orig TEXT/*VARCHAR(255)*/,
- fullName_norm TEXT/*VARCHAR(255)*/,
- givenName_orig TEXT/*VARCHAR(255)*/,
- givenName_norm TEXT/*VARCHAR(255)*/,
- honorificPrefix_orig TEXT/*VARCHAR(255)*/,
- honorificPrefix_norm TEXT/*VARCHAR(255)*/,
- honorificSuffix_orig TEXT/*VARCHAR(255)*/,
- honorificSuffix_norm TEXT/*VARCHAR(255)*/,
- nickName_orig TEXT/*VARCHAR(255)*/,
- nickName_norm TEXT/*VARCHAR(255)*/,
- title_orig TEXT/*VARCHAR(255)*/,
- title_norm TEXT/*VARCHAR(255)*/
+ additionalName_orig TEXT,
+ additionalName_norm TEXT,
+ employeeNumber TEXT,
+ familyName_orig TEXT,
+ familyName_norm TEXT,
+ fullName_orig TEXT,
+ fullName_norm TEXT,
+ givenName_orig TEXT,
+ givenName_norm TEXT,
+ honorificPrefix_orig TEXT,
+ honorificPrefix_norm TEXT,
+ honorificSuffix_orig TEXT,
+ honorificSuffix_norm TEXT,
+ nickName_orig TEXT,
+ nickName_norm TEXT,
+ title_orig TEXT,
+ title_norm TEXT
)
INHERITS (m_focus);
@@ -484,13 +484,13 @@ CREATE INDEX m_user_employeeNumber_idx ON m_user (employeeNumber);
/* TODO JSON of polystrings?
CREATE TABLE m_user_organization (
user_oid UUID NOT NULL,
- norm TEXT/*VARCHAR(255)*/,
- orig TEXT/*VARCHAR(255)*/
+ norm TEXT,
+ orig TEXT
);
CREATE TABLE m_user_organizational_unit (
user_oid UUID NOT NULL,
- norm TEXT/*VARCHAR(255)*/,
- orig TEXT/*VARCHAR(255)*/
+ norm TEXT,
+ orig TEXT
);
*/
-- endregion
@@ -501,11 +501,11 @@ CREATE TABLE m_abstract_role (
-- will be overridden with GENERATED value in concrete table
objectType ObjectType NOT NULL,
autoAssignEnabled BOOLEAN,
- displayName_orig TEXT/*VARCHAR(255)*/,
- displayName_norm TEXT/*VARCHAR(255)*/,
- identifier TEXT/*VARCHAR(255)*/,
+ displayName_orig TEXT,
+ displayName_norm TEXT,
+ identifier TEXT,
requestable BOOLEAN,
- riskLevel TEXT/*VARCHAR(255)*/,
+ riskLevel TEXT,
CHECK (FALSE) NO INHERIT
)
@@ -515,7 +515,7 @@ CREATE TABLE m_abstract_role (
CREATE TABLE m_role (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('ROLE') STORED,
- roleType TEXT/*VARCHAR(255)*/
+ roleType TEXT
)
INHERITS (m_abstract_role);
@@ -627,7 +627,7 @@ CREATE TABLE m_access_cert_case (
containerType ContainerType GENERATED ALWAYS AS ('ACCESS_CERTIFICATION_CASE') STORED,
administrativeStatus INTEGER,
archiveTimestamp TIMESTAMPTZ,
- disableReason TEXT/*VARCHAR(255)*/,
+ disableReason TEXT,
disableTimestamp TIMESTAMPTZ,
effectiveStatus INTEGER,
enableTimestamp TIMESTAMPTZ,
@@ -635,7 +635,7 @@ CREATE TABLE m_access_cert_case (
validTo TIMESTAMPTZ,
validityChangeTimestamp TIMESTAMPTZ,
validityStatus INTEGER,
- currentStageOutcome TEXT/*VARCHAR(255)*/,
+ currentStageOutcome TEXT,
fullObject BYTEA,
iteration INTEGER NOT NULL,
objectRef_targetOid UUID,
@@ -644,7 +644,7 @@ CREATE TABLE m_access_cert_case (
orgRef_targetOid UUID,
orgRef_targetType ObjectType,
orgRef_relation_id INTEGER REFERENCES m_uri(id),
- outcome TEXT/*VARCHAR(255)*/,
+ outcome TEXT,
remediedTimestamp TIMESTAMPTZ,
reviewDeadline TIMESTAMPTZ,
reviewRequestedTimestamp TIMESTAMPTZ,
@@ -666,7 +666,7 @@ CREATE TABLE m_access_cert_wi (
containerType ContainerType GENERATED ALWAYS AS ('ACCESS_CERTIFICATION_WORK_ITEM') STORED,
closeTimestamp TIMESTAMPTZ,
iteration INTEGER NOT NULL,
- outcome TEXT/*VARCHAR(255)*/,
+ outcome TEXT,
outputChangeTimestamp TIMESTAMPTZ,
performerRef_targetOid UUID,
performerRef_targetType ObjectType,
@@ -758,14 +758,14 @@ CREATE TABLE m_shadow (
resourceRef_targetOid UUID,
resourceRef_targetType ObjectType,
resourceRef_relation_id INTEGER REFERENCES m_uri(id),
- intent TEXT/*VARCHAR(255)*/,
+ intent TEXT,
kind ShadowKindType,
attemptNumber INTEGER, -- TODO how is this mapped?
dead BOOLEAN,
exist BOOLEAN,
fullSynchronizationTimestamp TIMESTAMPTZ,
pendingOperationCount INTEGER,
- primaryIdentifierValue TEXT/*VARCHAR(255)*/,
+ primaryIdentifierValue TEXT,
-- status INTEGER, TODO how is this mapped? See RUtil.copyResultFromJAXB called from RTask and OperationResultMapper
synchronizationSituation SynchronizationSituationType,
synchronizationTimestamp TIMESTAMPTZ
@@ -804,7 +804,7 @@ ALTER TABLE m_shadow ADD CONSTRAINT iPrimaryIdentifierValueWithOC
CREATE TABLE m_node (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('NODE') STORED,
- nodeIdentifier TEXT/*VARCHAR(255)*/
+ nodeIdentifier TEXT
)
INHERITS (m_object);
@@ -963,10 +963,10 @@ ALTER TABLE m_lookup_table ADD CONSTRAINT m_lookup_table_name_norm_key UNIQUE (n
CREATE TABLE m_lookup_table_row (
owner_oid UUID NOT NULL REFERENCES m_lookup_table(oid) ON DELETE CASCADE,
containerType ContainerType GENERATED ALWAYS AS ('LOOKUP_TABLE_ROW') STORED,
- key TEXT/*VARCHAR(255)*/,
- value TEXT/*VARCHAR(255)*/,
- label_orig TEXT/*VARCHAR(255)*/,
- label_norm TEXT/*VARCHAR(255)*/,
+ key TEXT,
+ value TEXT,
+ label_orig TEXT,
+ label_norm TEXT,
lastChangeTimestamp TIMESTAMPTZ,
PRIMARY KEY (owner_oid, cid)
@@ -980,9 +980,9 @@ ALTER TABLE m_lookup_table_row
CREATE TABLE m_connector (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('CONNECTOR') STORED,
- connectorBundle TEXT/*VARCHAR(255)*/, -- typically a package name
- connectorType TEXT/*VARCHAR(255)*/, -- typically a class name
- connectorVersion TEXT/*VARCHAR(255)*/,
+ connectorBundle TEXT, -- typically a package name
+ connectorType TEXT, -- typically a class name
+ connectorVersion TEXT,
framework_id INTEGER REFERENCES m_uri(id),
connectorHostRef_targetOid UUID,
connectorHostRef_targetType ObjectType,
@@ -1004,7 +1004,7 @@ ALTER TABLE m_connector ADD CONSTRAINT m_connector_name_norm_key UNIQUE (name_no
-- TODO array/json in m_connector table
-- CREATE TABLE m_connector_target_system (
-- connector_oid UUID NOT NULL,
--- targetSystemType TEXT/*VARCHAR(255)*/
+-- targetSystemType TEXT
-- );
-- ALTER TABLE m_connector_target_system
-- ADD CONSTRAINT fk_connector_target_system FOREIGN KEY (connector_oid) REFERENCES m_connector;
@@ -1013,8 +1013,8 @@ ALTER TABLE m_connector ADD CONSTRAINT m_connector_name_norm_key UNIQUE (name_no
CREATE TABLE m_connector_host (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('CONNECTOR_HOST') STORED,
- hostname TEXT/*VARCHAR(255)*/,
- port TEXT/*VARCHAR(32)*/
+ hostname TEXT,
+ port TEXT
)
INHERITS (m_object);
@@ -1032,23 +1032,23 @@ ALTER TABLE m_connector_host ADD CONSTRAINT m_connector_host_name_norm_key UNIQU
CREATE TABLE m_task (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('TASK') STORED,
- taskIdentifier TEXT/*VARCHAR(255)*/,
+ taskIdentifier TEXT,
binding TaskBindingType,
- category TEXT/*VARCHAR(255)*/,
+ category TEXT,
completionTimestamp TIMESTAMPTZ,
executionStatus TaskExecutionStateType,
fullResult BYTEA,
handlerUri_id INTEGER REFERENCES m_uri(id),
lastRunStartTimestamp TIMESTAMPTZ,
lastRunFinishTimestamp TIMESTAMPTZ,
- node TEXT/*VARCHAR(255)*/, -- node_id only for information purposes
+ node TEXT, -- node_id only for information purposes
objectRef_targetOid UUID,
objectRef_targetType ObjectType,
objectRef_relation_id INTEGER REFERENCES m_uri(id),
ownerRef_targetOid UUID,
ownerRef_targetType ObjectType,
ownerRef_relation_id INTEGER REFERENCES m_uri(id),
- parent TEXT/*VARCHAR(255)*/, -- value of taskIdentifier
+ parent TEXT, -- value of taskIdentifier
recurrence TaskRecurrenceType,
resultStatus OperationResultStatusType,
threadStopAction ThreadStopActionType,
@@ -1075,7 +1075,7 @@ CREATE INDEX m_task_dependentTaskIdentifiers_idx ON m_task USING GIN(dependentTa
CREATE TABLE m_case (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('CASE') STORED,
- state TEXT/*VARCHAR(255)*/,
+ state TEXT,
closeTimestamp TIMESTAMPTZ,
objectRef_targetOid UUID,
objectRef_targetType ObjectType,
@@ -1198,21 +1198,19 @@ CREATE INDEX m_form_name_orig_idx ON m_form (name_orig);
ALTER TABLE m_form ADD CONSTRAINT m_form_name_norm_key UNIQUE (name_norm);
-- endregion
--- region Assignment/Inducement tables
+-- region Assignment/Inducement table
-- Represents AssignmentType, see https://wiki.evolveum.com/display/midPoint/Assignment
-- and also https://wiki.evolveum.com/display/midPoint/Assignment+vs+Inducement
--- TODO: if we never need mix of inducements and assignments then let's have two separate tables
--- consult with Rado/Katka/Palo
--- TODO: partitioning, not by object type, it's not even... hash-something?
+-- TODO: partitioning, probably not by object type, it's not even... hash-something?
-- select assignmentowner, count(*) From m_assignment group by assignmentowner;
--1 45 (inducements)
--0 48756229
--- abstract common structure for m_assignment and m_inducement
-CREATE TABLE m_assignment_type (
- -- owner_oid + containerType from m_container, final specification in sub-tables
- -- new column may avoid join to object for some queries
+CREATE TABLE m_assignment (
+ owner_oid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
+ -- this is different from other containers, this is not generated, app must provide it
+ containerType ContainerType NOT NULL CHECK (containerType IN ('ASSIGNMENT', 'INDUCEMENT')),
owner_type ObjectType NOT NULL,
- lifecycleState TEXT/*VARCHAR(255)*/,
+ lifecycleState TEXT,
orderValue INTEGER,
orgRef_targetOid UUID,
orgRef_targetType ObjectType,
@@ -1225,7 +1223,7 @@ CREATE TABLE m_assignment_type (
tenantRef_relation_id INTEGER REFERENCES m_uri(id),
-- TODO what is this? see RAssignment.getExtension (both extId/Oid)
extId INTEGER,
- extOid TEXT/*VARCHAR(36)*/, -- is this UUID too?
+ extOid TEXT, -- is this UUID too?
policySituations INTEGER[], -- soft-references m_uri, add index per table
ext JSONB,
-- construction
@@ -1237,7 +1235,7 @@ CREATE TABLE m_assignment_type (
effectiveStatus ActivationStatusType,
enableTimestamp TIMESTAMPTZ,
disableTimestamp TIMESTAMPTZ,
- disableReason TEXT/*VARCHAR(255)*/,
+ disableReason TEXT,
validityStatus TimeIntervalStatusType,
validFrom TIMESTAMPTZ,
validTo TIMESTAMPTZ,
@@ -1255,21 +1253,9 @@ CREATE TABLE m_assignment_type (
modifyChannel_id INTEGER,
modifyTimestamp TIMESTAMPTZ,
- -- create PRIMARY KEY (owner_oid, cid) on sub-tables
- -- no need to index owner_oid, it's part of the PK index
-
- CHECK (FALSE) NO INHERIT
-)
- INHERITS(m_container);
-
-CREATE TABLE m_assignment (
- owner_oid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
- containerType ContainerType GENERATED ALWAYS AS ('ASSIGNMENT') STORED,
-
PRIMARY KEY (owner_oid, cid)
- -- no need to index owner_oid, it's part of the PK index
)
- INHERITS(m_assignment_type);
+ INHERITS(m_container);
CREATE INDEX m_assignment_policySituation_idx ON m_assignment USING GIN(policysituations gin__int_ops);
CREATE INDEX m_assignment_ext_idx ON m_assignment USING gin (ext);
@@ -1313,25 +1299,6 @@ ALTER TABLE m_assignment_ref_modify_approver ADD CONSTRAINT m_assignment_ref_mod
FOREIGN KEY (owner_oid, assignment_cid) REFERENCES m_assignment (owner_oid, cid);
-- TODO index targetOid, relation_id?
-
-CREATE TABLE m_inducement (
- owner_oid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
- containerType ContainerType GENERATED ALWAYS AS ('INDUCEMENT') STORED,
-
- PRIMARY KEY (owner_oid, cid)
- -- no need to index owner_oid, it's part of the PK index
-)
- INHERITS(m_assignment_type);
-
-CREATE INDEX m_inducement_ext_idx ON m_inducement USING gin (ext);
-CREATE INDEX m_inducement_validFrom_idx ON m_inducement (validFrom);
-CREATE INDEX m_inducement_validTo_idx ON m_inducement (validTo);
-CREATE INDEX m_inducement_targetRef_targetOid_idx ON m_inducement (targetRef_targetOid);
-CREATE INDEX m_inducement_tenantRef_targetOid_idx ON m_inducement (tenantRef_targetOid);
-CREATE INDEX m_inducement_orgRef_targetOid_idx ON m_inducement (orgRef_targetOid);
-CREATE INDEX m_inducement_resourceRef_targetOid_idx ON m_inducement (resourceRef_targetOid);
-
--- TODO other tables like for assignments needed? policy situations, refs?
-- endregion
-- region Other object containers
@@ -1380,10 +1347,10 @@ CREATE INDEX m_operation_execution_timestampValue_idx ON m_operation_execution (
CREATE TABLE m_ext_item (
id SERIAL NOT NULL,
kind INTEGER, -- see RItemKind, is this necessary? does it contain cardinality?
- name TEXT/*VARCHAR(157)*/, -- no path for nested props needed?
- type TEXT/*VARCHAR(32)*/, -- data type TODO enum?
- storageType TEXT/*VARCHAR(32)*/ NOT NULL default 'EXT_JSON', -- type of storage (JSON, column, table separate/common, etc.)
- storageInfo TEXT/*VARCHAR(32)*/, -- optional storage detail, name of column or table if necessary
+ name TEXT, -- no path for nested props needed?
+ type TEXT, -- data type TODO enum?
+ storageType TEXT NOT NULL default 'EXT_JSON', -- type of storage (JSON, column, table separate/common, etc.)
+ storageInfo TEXT, -- optional storage detail, name of column or table if necessary
PRIMARY KEY (id)
);
@@ -1412,8 +1379,8 @@ CREATE TABLE m_object_ext_long (
CREATE TABLE m_object_ext_poly (
owner_oid UUID NOT NULL REFERENCES m_object_oid(oid),
ext_item_id VARCHAR(32) NOT NULL,
- orig TEXT/*VARCHAR(255)*/ NOT NULL,
- norm TEXT/*VARCHAR(255)*/,
+ orig TEXT NOT NULL,
+ norm TEXT,
PRIMARY KEY (owner_oid, ext_item_id, orig)
);
CREATE TABLE m_object_ext_reference (
@@ -1427,7 +1394,7 @@ CREATE TABLE m_object_ext_reference (
CREATE TABLE m_object_ext_string (
owner_oid UUID NOT NULL REFERENCES m_object_oid(oid),
ext_item_id VARCHAR(32) NOT NULL,
- value TEXT/*VARCHAR(255)*/ NOT NULL,
+ value TEXT NOT NULL,
PRIMARY KEY (owner_oid, ext_item_id, value)
);
@@ -1463,8 +1430,8 @@ CREATE TABLE m_assignment_ext_poly (
item_id INTEGER NOT NULL,
anyContainer_owner_id INTEGER NOT NULL,
anyContainer_owner_owner_oid UUID NOT NULL,
- orig TEXT/*VARCHAR(255)*/ NOT NULL,
- norm TEXT/*VARCHAR(255)*/,
+ orig TEXT NOT NULL,
+ norm TEXT,
PRIMARY KEY (anyContainer_owner_owner_oid, anyContainer_owner_id, item_id, orig)
);
CREATE TABLE m_assignment_ext_reference (
@@ -1480,7 +1447,7 @@ CREATE TABLE m_assignment_ext_string (
item_id INTEGER NOT NULL,
anyContainer_owner_id INTEGER NOT NULL,
anyContainer_owner_owner_oid UUID NOT NULL,
- stringValue TEXT/*VARCHAR(255)*/ NOT NULL,
+ stringValue TEXT NOT NULL,
PRIMARY KEY (anyContainer_owner_owner_oid, anyContainer_owner_id, item_id, stringValue)
);
CREATE TABLE m_assignment_extension (
@@ -1498,42 +1465,42 @@ CREATE TABLE m_audit_delta (
deltaOid UUID,
deltaType INTEGER,
fullResult BYTEA,
- objectName_norm TEXT/*VARCHAR(255)*/,
- objectName_orig TEXT/*VARCHAR(255)*/,
- resourceName_norm TEXT/*VARCHAR(255)*/,
- resourceName_orig TEXT/*VARCHAR(255)*/,
+ objectName_norm TEXT,
+ objectName_orig TEXT,
+ resourceName_norm TEXT,
+ resourceName_orig TEXT,
resourceOid UUID,
status INTEGER,
PRIMARY KEY (record_id, checksum)
);
CREATE TABLE m_audit_event (
id BIGSERIAL NOT NULL,
- attorneyName TEXT/*VARCHAR(255)*/,
+ attorneyName TEXT,
attorneyOid UUID,
- channel TEXT/*VARCHAR(255)*/,
- eventIdentifier TEXT/*VARCHAR(255)*/,
+ channel TEXT,
+ eventIdentifier TEXT,
eventStage INTEGER,
eventType INTEGER,
- hostIdentifier TEXT/*VARCHAR(255)*/,
- initiatorName TEXT/*VARCHAR(255)*/,
+ hostIdentifier TEXT,
+ initiatorName TEXT,
initiatorOid UUID,
initiatorType INTEGER,
message VARCHAR(1024),
- nodeIdentifier TEXT/*VARCHAR(255)*/,
+ nodeIdentifier TEXT,
outcome INTEGER,
- parameter TEXT/*VARCHAR(255)*/,
- remoteHostAddress TEXT/*VARCHAR(255)*/,
- requestIdentifier TEXT/*VARCHAR(255)*/,
- result TEXT/*VARCHAR(255)*/,
- sessionIdentifier TEXT/*VARCHAR(255)*/,
- targetName TEXT/*VARCHAR(255)*/,
+ parameter TEXT,
+ remoteHostAddress TEXT,
+ requestIdentifier TEXT,
+ result TEXT,
+ sessionIdentifier TEXT,
+ targetName TEXT,
targetOid UUID,
- targetOwnerName TEXT/*VARCHAR(255)*/,
+ targetOwnerName TEXT,
targetOwnerOid UUID,
targetOwnerType INTEGER,
targetType INTEGER,
- taskIdentifier TEXT/*VARCHAR(255)*/,
- taskOID TEXT/*VARCHAR(255)*/,
+ taskIdentifier TEXT,
+ taskOID TEXT,
timestampValue TIMESTAMPTZ,
PRIMARY KEY (id)
);
@@ -1544,23 +1511,23 @@ CREATE TABLE m_audit_item (
);
CREATE TABLE m_audit_prop_value (
id BIGSERIAL NOT NULL,
- name TEXT/*VARCHAR(255)*/,
+ name TEXT,
record_id BIGINT,
value VARCHAR(1024),
PRIMARY KEY (id)
);
CREATE TABLE m_audit_ref_value (
id BIGSERIAL NOT NULL,
- name TEXT/*VARCHAR(255)*/,
+ name TEXT,
oid UUID,
record_id BIGINT,
- targetName_norm TEXT/*VARCHAR(255)*/,
- targetName_orig TEXT/*VARCHAR(255)*/,
- type TEXT/*VARCHAR(255)*/,
+ targetName_norm TEXT,
+ targetName_orig TEXT,
+ type TEXT,
PRIMARY KEY (id)
);
CREATE TABLE m_audit_resource (
- resourceOid TEXT/*VARCHAR(255)*/ NOT NULL,
+ resourceOid TEXT NOT NULL,
record_id BIGINT NOT NULL,
PRIMARY KEY (record_id, resourceOid)
);
@@ -1573,7 +1540,7 @@ CREATE TABLE m_case_wi (
originalAssigneeRef_relation VARCHAR(157),
originalAssigneeRef_targetOid UUID,
originalAssigneeRef_targetType INTEGER,
- outcome TEXT/*VARCHAR(255)*/,
+ outcome TEXT,
performerRef_relation VARCHAR(157),
performerRef_targetOid UUID,
performerRef_targetType INTEGER,
@@ -1621,8 +1588,8 @@ CREATE TABLE m_object_ext_poly (
item_id INTEGER NOT NULL,
owner_oid UUID NOT NULL,
ownerType INTEGER NOT NULL,
- orig TEXT/*VARCHAR(255)*/ NOT NULL,
- norm TEXT/*VARCHAR(255)*/,
+ orig TEXT NOT NULL,
+ norm TEXT,
PRIMARY KEY (owner_oid, ownerType, item_id, orig)
);
CREATE TABLE m_object_ext_reference (
@@ -1638,7 +1605,7 @@ CREATE TABLE m_object_ext_string (
item_id INTEGER NOT NULL,
owner_oid UUID NOT NULL,
ownerType INTEGER NOT NULL,
- stringValue TEXT/*VARCHAR(255)*/ NOT NULL,
+ stringValue TEXT NOT NULL,
PRIMARY KEY (owner_oid, ownerType, item_id, stringValue)
);
CREATE TABLE m_org_closure (
@@ -1650,8 +1617,8 @@ CREATE TABLE m_org_closure (
CREATE TABLE m_org (
displayOrder INTEGER,
- name_norm TEXT/*VARCHAR(255)*/,
- name_orig TEXT/*VARCHAR(255)*/,
+ name_norm TEXT,
+ name_orig TEXT,
tenant BOOLEAN,
oid UUID NOT NULL,
PRIMARY KEY (oid)
@@ -2047,8 +2014,8 @@ create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);
-- region Schema versioning and upgrading
CREATE TABLE m_global_metadata (
- name TEXT/*VARCHAR(255)*/ PRIMARY KEY,
- value TEXT/*VARCHAR(255)*/
+ name TEXT PRIMARY KEY,
+ value TEXT
);
/*
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java
index cffe745ec8d..1c603666c79 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleQueryContext.java
@@ -15,18 +15,16 @@
import com.evolveum.midpoint.repo.sqale.filtering.InOidFilterProcessor;
import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext;
-import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext;
import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping;
-import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
public class SqaleQueryContext, R>
extends SqlQueryContext {
public static , R> SqaleQueryContext from(
- Class schemaType, SqaleTransformerSupport transformerSupport,
- SqlRepoContext sqlRepoContext) {
+ Class schemaType,
+ SqaleRepoContext sqlRepoContext) {
SqaleTableMapping rootMapping = sqlRepoContext.getMappingBySchemaType(schemaType);
Q rootPath = rootMapping.defaultAlias();
@@ -36,21 +34,20 @@ public static , R> SqaleQueryContext<
query.getMetadata().setValidate(true);
return new SqaleQueryContext<>(
- rootPath, rootMapping, transformerSupport, sqlRepoContext, query);
+ rootPath, rootMapping, sqlRepoContext, query);
}
private SqaleQueryContext(
Q entityPath,
SqaleTableMapping mapping,
- SqaleTransformerSupport transformerSupport,
- SqlRepoContext sqlRepoContext,
+ SqaleRepoContext sqlRepoContext,
SQLQuery> query) {
- super(entityPath, mapping, sqlRepoContext, transformerSupport, query);
+ super(entityPath, mapping, sqlRepoContext, query);
}
@Override
- protected SqlTransformer createTransformer() {
- return entityPathMapping.createTransformer(transformerSupport);
+ public SqaleRepoContext repositoryContext() {
+ return (SqaleRepoContext) super.repositoryContext();
}
@Override
@@ -59,23 +56,19 @@ public FilterProcessor createInOidFilter(SqlQueryContext, ?, ?> c
}
public @NotNull Integer searchCachedRelationId(QName qName) {
- return transformerSupport().searchCachedRelationId(qName);
+ return repositoryContext().searchCachedRelationId(qName);
}
/**
- * Returns {@link SqaleQueryContext} - lot of ugly casting here, but it is not possible to
- * use covariant return type with covariant parametric types (narrower generics).
+ * Returns derived {@link SqaleQueryContext} for join or subquery.
*/
- @SuppressWarnings({ "rawtypes", "unchecked" })
@Override
protected , TR> SqlQueryContext
deriveNew(TQ newPath, QueryTableMapping newMapping) {
- return (SqlQueryContext) new SqaleQueryContext(
- newPath, (SqaleTableMapping, ?, ?>) newMapping,
- transformerSupport(), sqlRepoContext, sqlQuery);
- }
-
- private SqaleTransformerSupport transformerSupport() {
- return (SqaleTransformerSupport) transformerSupport;
+ return new SqaleQueryContext<>(
+ newPath,
+ (SqaleTableMapping) newMapping,
+ repositoryContext(),
+ sqlQuery);
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java
index b46b6eea22d..bfbc3dccb50 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepoContext.java
@@ -14,12 +14,15 @@
import org.jetbrains.annotations.NotNull;
import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType;
+import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType;
import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReferenceType;
import com.evolveum.midpoint.repo.sqlbase.JdbcRepositoryConfiguration;
import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext;
import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry;
import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslJsonbType;
+import com.evolveum.midpoint.schema.SchemaService;
+import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
/**
@@ -32,8 +35,9 @@ public class SqaleRepoContext extends SqlRepoContext {
public SqaleRepoContext(
JdbcRepositoryConfiguration jdbcRepositoryConfiguration,
DataSource dataSource,
+ SchemaService schemaService,
QueryModelMappingRegistry mappingRegistry) {
- super(jdbcRepositoryConfiguration, dataSource, mappingRegistry);
+ super(jdbcRepositoryConfiguration, dataSource, schemaService, mappingRegistry);
// each enum type must be registered if we want to map it as objects (to PG enum types)
querydslConfig.register(new EnumAsObjectType<>(ActivationStatusType.class));
@@ -67,29 +71,32 @@ public void clearCaches() {
uriCache.initialize(this::newJdbcSession);
}
- /** @see UriCache#searchId(QName) */
- @NotNull
- public Integer searchCachedUriId(QName qName) {
- return uriCache.searchId(qName);
- }
-
/** @see UriCache#searchId(String) */
public Integer searchCachedUriId(String uri) {
return uriCache.searchId(uri);
}
- /** @see UriCache#resolveUriToId(String) */
- public @NotNull Integer resolveUriToId(String uri) {
- return uriCache.resolveUriToId(uri);
- }
-
- /** @see UriCache#resolveUriToId(QName) */
- public Integer resolveUriToId(QName uri) {
- return uriCache.resolveUriToId(uri);
+ /**
+ * Returns ID for relation QName or {@link UriCache#UNKNOWN_ID} without going to the database.
+ * Relation is normalized before consulting {@link UriCache}.
+ * Never returns null; returns default ID for configured default relation if provided with null.
+ */
+ public @NotNull Integer searchCachedRelationId(QName qName) {
+ return searchCachedUriId(QNameUtil.qNameToUri(normalizeRelation(qName)));
}
/** Returns ID for URI creating new cache row in DB as needed. */
public Integer processCacheableUri(String uri) {
return uriCache.processCacheableUri(uri);
}
+
+ /**
+ * Returns ID for relation QName creating new {@link QUri} row in DB as needed.
+ * Relation is normalized before consulting the cache.
+ * Never returns null, returns default ID for configured default relation.
+ */
+ public Integer processCacheableRelation(QName qName) {
+ return processCacheableUri(
+ QNameUtil.qNameToUri(normalizeRelation(qName)));
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java
index 800f72f08e5..408168f3cf4 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleRepositoryBeanConfig.java
@@ -110,49 +110,66 @@ public DataSource dataSource(DataSourceFactory dataSourceFactory)
@Bean
public SqaleRepoContext sqlRepoContext(
SqaleRepositoryConfiguration repositoryConfiguration,
+ SchemaService schemaService,
DataSource dataSource) {
- QueryModelMappingRegistry mappingRegistry = new QueryModelMappingRegistry()
- // ordered alphabetically here, mappings without schema type at the end
- .register(AbstractRoleType.COMPLEX_TYPE, QAbstractRoleMapping.INSTANCE)
+ QueryModelMappingRegistry mappingRegistry = new QueryModelMappingRegistry();
+ SqaleRepoContext repositoryContext = new SqaleRepoContext(
+ repositoryConfiguration, dataSource, schemaService, mappingRegistry);
+
+ // Registered mapping needs repository context which needs registry. Now we can fill it.
+ // Mappings are ordered alphabetically here, mappings without schema type are at the end.
+ mappingRegistry
+ .register(AbstractRoleType.COMPLEX_TYPE,
+ QAbstractRoleMapping.init(repositoryContext))
.register(AccessCertificationDefinitionType.COMPLEX_TYPE,
- QAccessCertificationDefinitionMapping.INSTANCE)
- .register(ArchetypeType.COMPLEX_TYPE, QArchetypeMapping.INSTANCE)
- .register(AssignmentHolderType.COMPLEX_TYPE, QAssignmentHolderMapping.INSTANCE)
- .register(AssignmentType.COMPLEX_TYPE, QAssignmentMapping.INSTANCE)
- .register(CaseType.COMPLEX_TYPE, QCaseMapping.INSTANCE)
- .register(DashboardType.COMPLEX_TYPE, QDashboardMapping.INSTANCE)
- .register(FocusType.COMPLEX_TYPE, QFocusMapping.INSTANCE)
- .register(FormType.COMPLEX_TYPE, QFormMapping.INSTANCE)
- .register(FunctionLibraryType.COMPLEX_TYPE, QFunctionLibraryMapping.INSTANCE)
- .register(ConnectorType.COMPLEX_TYPE, QConnectorMapping.INSTANCE)
- .register(ConnectorHostType.COMPLEX_TYPE, QConnectorHostMapping.INSTANCE)
- .register(GenericObjectType.COMPLEX_TYPE, QGenericObjectMapping.INSTANCE)
- .register(LookupTableType.COMPLEX_TYPE, QLookupTableMapping.INSTANCE)
- .register(LookupTableRowType.COMPLEX_TYPE, QLookupTableRowMapping.INSTANCE)
- .register(NodeType.COMPLEX_TYPE, QNodeMapping.INSTANCE)
- .register(ObjectType.COMPLEX_TYPE, QObjectMapping.INSTANCE)
- .register(ObjectTemplateType.COMPLEX_TYPE, QObjectTemplateMapping.INSTANCE)
- .register(ObjectCollectionType.COMPLEX_TYPE, QObjectCollectionMapping.INSTANCE)
- .register(OperationExecutionType.COMPLEX_TYPE, QOperationExecutionMapping.INSTANCE)
- .register(ReportType.COMPLEX_TYPE, QReportMapping.INSTANCE)
- .register(ReportDataType.COMPLEX_TYPE, QReportDataMapping.INSTANCE)
- .register(ResourceType.COMPLEX_TYPE, QResourceMapping.INSTANCE)
- .register(RoleType.COMPLEX_TYPE, QRoleMapping.INSTANCE)
- .register(SecurityPolicyType.COMPLEX_TYPE, QSecurityPolicyMapping.INSTANCE)
- .register(SequenceType.COMPLEX_TYPE, QSequenceMapping.INSTANCE)
- .register(ServiceType.COMPLEX_TYPE, QServiceMapping.INSTANCE)
- .register(ShadowType.COMPLEX_TYPE, QShadowMapping.INSTANCE)
+ QAccessCertificationDefinitionMapping.init(repositoryContext))
+ .register(ArchetypeType.COMPLEX_TYPE, QArchetypeMapping.init(repositoryContext))
+ .register(AssignmentHolderType.COMPLEX_TYPE,
+ QAssignmentHolderMapping.init(repositoryContext))
+ .register(AssignmentType.COMPLEX_TYPE,
+ QAssignmentMapping.initAssignment(repositoryContext))
+ .register(CaseType.COMPLEX_TYPE, QCaseMapping.init(repositoryContext))
+ .register(DashboardType.COMPLEX_TYPE, QDashboardMapping.init(repositoryContext))
+ .register(FocusType.COMPLEX_TYPE, QFocusMapping.init(repositoryContext))
+ .register(FormType.COMPLEX_TYPE, QFormMapping.init(repositoryContext))
+ .register(FunctionLibraryType.COMPLEX_TYPE,
+ QFunctionLibraryMapping.init(repositoryContext))
+ .register(ConnectorType.COMPLEX_TYPE, QConnectorMapping.init(repositoryContext))
+ .register(ConnectorHostType.COMPLEX_TYPE,
+ QConnectorHostMapping.init(repositoryContext))
+ .register(GenericObjectType.COMPLEX_TYPE,
+ QGenericObjectMapping.init(repositoryContext))
+ .register(LookupTableType.COMPLEX_TYPE, QLookupTableMapping.init(repositoryContext))
+ .register(LookupTableRowType.COMPLEX_TYPE,
+ QLookupTableRowMapping.init(repositoryContext))
+ .register(NodeType.COMPLEX_TYPE, QNodeMapping.init(repositoryContext))
+ .register(ObjectType.COMPLEX_TYPE, QObjectMapping.init(repositoryContext))
+ .register(ObjectCollectionType.COMPLEX_TYPE,
+ QObjectCollectionMapping.init(repositoryContext))
+ .register(ObjectTemplateType.COMPLEX_TYPE,
+ QObjectTemplateMapping.init(repositoryContext))
+ .register(OperationExecutionType.COMPLEX_TYPE,
+ QOperationExecutionMapping.init(repositoryContext))
+ .register(ReportType.COMPLEX_TYPE, QReportMapping.init(repositoryContext))
+ .register(ReportDataType.COMPLEX_TYPE, QReportDataMapping.init(repositoryContext))
+ .register(ResourceType.COMPLEX_TYPE, QResourceMapping.init(repositoryContext))
+ .register(RoleType.COMPLEX_TYPE, QRoleMapping.init(repositoryContext))
+ .register(SecurityPolicyType.COMPLEX_TYPE,
+ QSecurityPolicyMapping.init(repositoryContext))
+ .register(SequenceType.COMPLEX_TYPE, QSequenceMapping.init(repositoryContext))
+ .register(ServiceType.COMPLEX_TYPE, QServiceMapping.init(repositoryContext))
+ .register(ShadowType.COMPLEX_TYPE, QShadowMapping.init(repositoryContext))
.register(SystemConfigurationType.COMPLEX_TYPE,
- QSystemConfigurationMapping.INSTANCE)
- .register(TaskType.COMPLEX_TYPE, QTaskMapping.INSTANCE)
- .register(TriggerType.COMPLEX_TYPE, QTriggerMapping.INSTANCE)
- .register(UserType.COMPLEX_TYPE, QUserMapping.INSTANCE)
- .register(ValuePolicyType.COMPLEX_TYPE, QValuePolicyMapping.INSTANCE)
- .register(QContainerMapping.INSTANCE)
- .register(QReferenceMapping.INSTANCE)
+ QSystemConfigurationMapping.init(repositoryContext))
+ .register(TaskType.COMPLEX_TYPE, QTaskMapping.init(repositoryContext))
+ .register(TriggerType.COMPLEX_TYPE, QTriggerMapping.init(repositoryContext))
+ .register(UserType.COMPLEX_TYPE, QUserMapping.init(repositoryContext))
+ .register(ValuePolicyType.COMPLEX_TYPE, QValuePolicyMapping.init(repositoryContext))
+ .register(QContainerMapping.initContainerMapping(repositoryContext))
+ .register(QReferenceMapping.init(repositoryContext))
.seal();
- return new SqaleRepoContext(repositoryConfiguration, dataSource, mappingRegistry);
+ return repositoryContext;
}
@Bean
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 47dfa1f6840..8613d581234 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
@@ -54,9 +54,7 @@
/**
* Repository implementation based on SQL, JDBC and Querydsl without any ORM.
- * WORK IN PROGRESS:
- * It will be PostgreSQL only or at least PG optimized with generic SQL support for other unsupported DB.
- * Possible Oracle support is in play.
+ * WORK IN PROGRESS.
*/
public class SqaleRepositoryService implements RepositoryService {
@@ -71,10 +69,9 @@ public class SqaleRepositoryService implements RepositoryService {
private static final int MAX_CONFLICT_WATCHERS = 10;
- private final SqaleRepoContext sqlRepoContext;
+ private final SqaleRepoContext repositoryContext;
private final SchemaService schemaService;
private final SqlQueryExecutor sqlQueryExecutor;
- private final SqaleTransformerSupport transformerSupport;
private final SqlPerformanceMonitorsCollection sqlPerformanceMonitorsCollection;
// TODO: see comment in the SystemConfigurationChangeDispatcherImpl for related issues
@@ -86,17 +83,16 @@ public class SqaleRepositoryService implements RepositoryService {
private SqlPerformanceMonitorImpl performanceMonitor; // set to null in destroy
public SqaleRepositoryService(
- SqaleRepoContext sqlRepoContext,
+ SqaleRepoContext repositoryContext,
SchemaService schemaService,
SqlPerformanceMonitorsCollection sqlPerformanceMonitorsCollection) {
- this.sqlRepoContext = sqlRepoContext;
+ this.repositoryContext = repositoryContext;
this.schemaService = schemaService;
- this.sqlQueryExecutor = new SqlQueryExecutor(sqlRepoContext);
- this.transformerSupport = new SqaleTransformerSupport(schemaService, sqlRepoContext);
+ this.sqlQueryExecutor = new SqlQueryExecutor(repositoryContext);
this.sqlPerformanceMonitorsCollection = sqlPerformanceMonitorsCollection;
// monitor initialization and registration
- JdbcRepositoryConfiguration config = sqlRepoContext.getJdbcRepositoryConfiguration();
+ JdbcRepositoryConfiguration config = repositoryContext.getJdbcRepositoryConfiguration();
performanceMonitor = new SqlPerformanceMonitorImpl(
config.getPerformanceStatisticsLevel(), config.getPerformanceStatisticsFile());
sqlPerformanceMonitorsCollection.register(performanceMonitor);
@@ -125,7 +121,7 @@ public SqaleRepositoryService(
try {
PrismObject object;
try (JdbcSession jdbcSession =
- sqlRepoContext.newJdbcSession().startReadOnlyTransaction()) {
+ repositoryContext.newJdbcSession().startReadOnlyTransaction()) {
//noinspection unchecked
object = (PrismObject) readByOid(jdbcSession, type, oidUuid, options)
.asPrismObject();
@@ -171,10 +167,10 @@ private S readByOid(
throws SchemaException, ObjectNotFoundException {
SqaleTableMapping, MObject> rootMapping =
- sqlRepoContext.getMappingBySchemaType(schemaType);
+ repositoryContext.getMappingBySchemaType(schemaType);
QObject root = rootMapping.defaultAlias();
- Tuple result = sqlRepoContext.newQuery(jdbcSession.connection())
+ Tuple result = repositoryContext.newQuery(jdbcSession.connection())
.from(root)
.select(rootMapping.selectExpressions(root, options))
.where(root.oid.eq(oid))
@@ -184,8 +180,7 @@ private S readByOid(
throw new ObjectNotFoundException(schemaType, oid.toString());
}
- return rootMapping.createTransformer(transformerSupport)
- .toSchemaObject(result, root, options);
+ return rootMapping.toSchemaObject(result, root, options);
}
@Override
@@ -258,7 +253,7 @@ public String addObject(
// TODO use executeAttempts
String oid = new AddObjectOperation<>(object, options, operationResult)
- .execute(transformerSupport);
+ .execute(repositoryContext);
invokeConflictWatchers((w) -> w.afterAddObject(oid, object));
return oid;
/*
@@ -359,7 +354,7 @@ public ModifyObjectResult modifyObject(
logTraceModifications(modifications);
// TODO: THIS is real start of modifyObjectAttempt
- try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
+ try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) {
RootUpdateContext, MObject> updateContext =
prepareUpdateContext(jdbcSession, type, oidUuid);
PrismObject prismObject = updateContext.getPrismObject();
@@ -402,10 +397,10 @@ RootUpdateContext prepareUpdateContext(
throws SchemaException, ObjectNotFoundException {
SqaleTableMapping, R> rootMapping =
- sqlRepoContext.getMappingBySchemaType(schemaType);
+ repositoryContext.getMappingBySchemaType(schemaType);
QObject root = rootMapping.defaultAlias();
- Tuple result = sqlRepoContext.newQuery(jdbcSession.connection())
+ Tuple result = repositoryContext.newQuery(jdbcSession.connection())
.select(root.oid, root.fullObject, root.containerIdSeq)
.from(root)
.where(root.oid.eq(oid))
@@ -416,8 +411,7 @@ RootUpdateContext prepareUpdateContext(
throw new ObjectNotFoundException(schemaType, oid.toString());
}
- S object = rootMapping.createTransformer(transformerSupport)
- .toSchemaObject(result, root, Collections.emptyList());
+ S object = rootMapping.toSchemaObject(result, root, Collections.emptyList());
R rootRow = rootMapping.newRowObject();
rootRow.oid = oid;
@@ -426,7 +420,7 @@ RootUpdateContext prepareUpdateContext(
rootRow.objectType = MObjectType.fromSchemaType(object.getClass());
// we don't care about full object in row
- return new RootUpdateContext<>(transformerSupport, jdbcSession, object, rootRow);
+ return new RootUpdateContext<>(repositoryContext, jdbcSession, object, rootRow);
}
private void logTraceModifications(@NotNull Collection extends ItemDelta, ?>> modifications) {
@@ -463,7 +457,7 @@ private void logTraceModifications(@NotNull Collection extends ItemDelta, ?>
.addParam("oid", oid)
.build();
try {
- try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
+ try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) {
DeleteObjectResult result = deleteObjectAttempt(type, oidUuid, jdbcSession);
invokeConflictWatchers((w) -> w.afterDeleteObject(oid));
@@ -484,8 +478,7 @@ private void logTraceModifications(@NotNull Collection extends ItemDelta, ?>
DeleteObjectResult deleteObjectAttempt(Class type, UUID oid, JdbcSession jdbcSession)
throws ObjectNotFoundException {
- QueryTableMapping mapping =
- transformerSupport.sqlRepoContext().getMappingBySchemaType(type);
+ QueryTableMapping mapping = repositoryContext.getMappingBySchemaType(type);
Q entityPath = mapping.defaultAlias();
byte[] fullObject = jdbcSession.newQuery()
.select(entityPath.fullObject)
@@ -522,7 +515,7 @@ public int countObjects(Class type, ObjectQuery query,
.build();
try {
- var queryContext = SqaleQueryContext.from(type, transformerSupport, sqlRepoContext);
+ var queryContext = SqaleQueryContext.from(type, repositoryContext);
return sqlQueryExecutor.count(queryContext, query, options);
} catch (RepositoryException | RuntimeException e) {
throw handledGeneralException(e, operationResult);
@@ -550,7 +543,7 @@ public int countObjects(Class type, ObjectQuery query,
.build();
try {
- var queryContext = SqaleQueryContext.from(type, transformerSupport, sqlRepoContext);
+ var queryContext = SqaleQueryContext.from(type, repositoryContext);
SearchResultList result =
sqlQueryExecutor.list(queryContext, query, options);
// TODO see the commented code from old repo lower, problems for each object must be caught
@@ -569,7 +562,7 @@ public int countObjects(Class type, ObjectQuery query,
/*
TODO from ObjectRetriever, how to do this per-object Throwable catch + record result?
- should we smuggle the OperationResult all the way to the transformer call?
+ should we smuggle the OperationResult all the way to the mapping call?
@NotNull
private List> queryResultToPrismObjects(
List objects, Class type,
@@ -633,7 +626,7 @@ public SearchResultList searchContainers(
.build();
try {
- var queryContext = SqaleQueryContext.from(type, transformerSupport, sqlRepoContext);
+ var queryContext = SqaleQueryContext.from(type, repositoryContext);
SearchResultList result =
sqlQueryExecutor.list(queryContext, query, options);
return result;
@@ -838,7 +831,7 @@ private SystemException handledGeneralException(@NotNull Throwable ex, Operation
// TODO reconsider this whole mechanism including isFatalException decision
LOGGER.error("General checked exception occurred.", ex);
recordException(ex, result,
- sqlRepoContext.getJdbcRepositoryConfiguration().isFatalException(ex));
+ repositoryContext.getJdbcRepositoryConfiguration().isFatalException(ex));
return ex instanceof SystemException
? (SystemException) ex
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java
deleted file mode 100644
index 0bf18204c9b..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/SqaleTransformerSupport.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 javax.xml.namespace.QName;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.schema.SchemaService;
-import com.evolveum.midpoint.util.QNameUtil;
-
-/**
- * Extension of {@link SqlTransformerSupport} adding Sqale features like {@link UriCache} support.
- */
-public class SqaleTransformerSupport extends SqlTransformerSupport {
-
- public SqaleTransformerSupport(SchemaService schemaService, SqaleRepoContext sqaleRepoContext) {
- super(schemaService, sqaleRepoContext);
- }
-
- private SqaleRepoContext sqaleRepoContext() {
- return (SqaleRepoContext) sqlRepoContext;
- }
-
- /**
- * Returns ID for relation QName or {@link UriCache#UNKNOWN_ID} without going to the database.
- * Relation is normalized before consulting {@link UriCache}.
- * Never returns null; returns default ID for configured default relation if provided with null.
- */
- public @NotNull Integer searchCachedRelationId(QName qName) {
- return sqaleRepoContext().searchCachedUriId(QNameUtil.qNameToUri(normalizeRelation(qName)));
- }
-
- /** Returns ID for cached URI without going to the database. */
- public Integer resolveUriToId(String uri) {
- return sqaleRepoContext().resolveUriToId(uri);
- }
-
- /** Returns ID for cached URI without going to the database. */
- public Integer resolveUriToId(QName uri) {
- return sqaleRepoContext().resolveUriToId(uri);
- }
-
- /**
- * Returns ID for relation QName creating new {@link QUri} row in DB as needed.
- * Relation is normalized before consulting the cache.
- * Never returns null, returns default ID for configured default relation.
- */
- public Integer processCacheableRelation(QName qName) {
- return processCacheableUri(
- QNameUtil.qNameToUri(normalizeRelation(qName)));
- }
-
- /** Returns ID for URI creating new cache row in DB as needed. */
- public Integer processCacheableUri(String uri) {
- return sqaleRepoContext().processCacheableUri(uri);
- }
-}
-
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java
index c31601cc86c..a9256c5d88d 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefItemDeltaProcessor.java
@@ -57,7 +57,8 @@ , R> RefItemDeltaProcessor(
public void setValue(Referencable value) {
context.set(oidPath, UUID.fromString(value.getOid()));
context.set(typePath, MObjectType.fromTypeQName(value.getType()));
- context.set(relationIdPath, context.processCacheableRelation(value.getRelation()));
+ context.set(relationIdPath,
+ context.repositoryContext().processCacheableRelation(value.getRelation()));
}
@Override
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java
index 011dbb6b2d3..2b106886e84 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/RefTableItemDeltaProcessor.java
@@ -46,7 +46,7 @@ public void addValues(Collection values) {
public void deleteValues(Collection values) {
Q r = refTableMapping.defaultAlias();
for (Referencable ref : values) {
- Integer relId = context.transformerSupport().searchCachedRelationId(ref.getRelation());
+ Integer relId = context.repositoryContext().searchCachedRelationId(ref.getRelation());
context.jdbcSession().newDelete(r)
.where(r.isOwnedBy(context.row())
.and(r.targetOid.eq(UUID.fromString(ref.getOid())))
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java
index c1acaf69af4..00e02ed2c52 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/delta/item/UriItemDeltaProcessor.java
@@ -29,6 +29,6 @@ public , R> UriItemDeltaProcessor(
@Override
public @Nullable Integer convertRealValue(Object realValue) {
- return context.processCacheableUri((String) realValue);
+ return context.repositoryContext().processCacheableUri((String) realValue);
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java
index b154daed1fc..2125d540458 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/filtering/UriItemFilterProcessor.java
@@ -36,6 +36,6 @@ public , R> UriItemFilterProcessor(
public Predicate process(PropertyValueFilter filter) throws QueryException {
return createBinaryCondition(filter, path,
ValueFilterValues.from(filter,
- u -> ((SqaleRepoContext) context.sqlRepoContext()).searchCachedUriId(u)));
+ u -> ((SqaleRepoContext) context.repositoryContext()).searchCachedUriId(u)));
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java
index 4e07ff7847e..c0614196cad 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/operations/AddObjectOperation.java
@@ -18,12 +18,11 @@
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.repo.api.RepoAddOptions;
import com.evolveum.midpoint.repo.sqale.ContainerValueIdGenerator;
-import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport;
-import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping;
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType;
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject;
+import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.SqlRepoContext;
import com.evolveum.midpoint.schema.result.OperationResult;
@@ -47,9 +46,9 @@ public class AddObjectOperation, R ex
private final RepoAddOptions options;
private final OperationResult result;
- private SqlRepoContext sqlRepoContext;
+ private SqlRepoContext repositoryContext;
private Q root;
- private ObjectSqlTransformer transformer;
+ private QObjectMapping rootMapping;
private MObjectType objectType;
public AddObjectOperation(@NotNull PrismObject object,
@@ -59,19 +58,18 @@ public AddObjectOperation(@NotNull PrismObject object,
this.result = result;
}
- /** Inserts the object provided to the constructor and returns its OID. */
- public String execute(SqaleTransformerSupport transformerSupport)
+ /**
+ * Inserts the object provided to the constructor and returns its OID.
+ */
+ public String execute(SqaleRepoContext repositoryContext)
throws SchemaException, ObjectAlreadyExistsException {
try {
// TODO utilize options and result
- sqlRepoContext = transformerSupport.sqlRepoContext();
+ this.repositoryContext = repositoryContext;
Class schemaObjectClass = object.getCompileTimeClass();
objectType = MObjectType.fromSchemaType(schemaObjectClass);
- SqaleTableMapping rootMapping =
- sqlRepoContext.getMappingBySchemaType(schemaObjectClass);
+ rootMapping = repositoryContext.getMappingBySchemaType(schemaObjectClass);
root = rootMapping.defaultAlias();
- transformer = (ObjectSqlTransformer)
- rootMapping.createTransformer(transformerSupport);
// we don't want CID generation here, because overwrite works different then normal add
@@ -98,11 +96,11 @@ private String overwriteObject() {
private String addObjectWithOid() throws SchemaException {
long lastCid = new ContainerValueIdGenerator().generateForNewObject(object);
- try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
+ try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) {
S schemaObject = object.asObjectable();
- R row = transformer.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
+ R row = rootMapping.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
row.containerIdSeq = lastCid + 1;
- transformer.setFullObject(row, schemaObject);
+ rootMapping.setFullObject(row, schemaObject);
UUID oid = jdbcSession.newInsert(root)
// default populate mapper ignores null, that's good, especially for objectType
@@ -110,7 +108,7 @@ private String addObjectWithOid() throws SchemaException {
.executeWithKey(root.oid);
row.objectType = objectType; // sub-entities can use it, now it's safe to set it
- transformer.storeRelatedEntities(row, schemaObject, jdbcSession);
+ rootMapping.storeRelatedEntities(row, schemaObject, jdbcSession);
jdbcSession.commit();
return Objects.requireNonNull(oid, "OID of inserted object can't be null")
@@ -119,9 +117,9 @@ private String addObjectWithOid() throws SchemaException {
}
private String addObjectWithoutOid() throws SchemaException {
- try (JdbcSession jdbcSession = sqlRepoContext.newJdbcSession().startTransaction()) {
+ try (JdbcSession jdbcSession = repositoryContext.newJdbcSession().startTransaction()) {
S schemaObject = object.asObjectable();
- R row = transformer.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
+ R row = rootMapping.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
// first insert without full object, because we don't know the OID yet
UUID oid = jdbcSession.newInsert(root)
@@ -136,7 +134,7 @@ private String addObjectWithoutOid() throws SchemaException {
long lastCid = new ContainerValueIdGenerator().generateForNewObject(object);
// now to update full object with known OID
- transformer.setFullObject(row, schemaObject);
+ rootMapping.setFullObject(row, schemaObject);
jdbcSession.newUpdate(root)
.set(root.fullObject, row.fullObject)
.set(root.containerIdSeq, lastCid + 1)
@@ -145,7 +143,7 @@ private String addObjectWithoutOid() throws SchemaException {
row.oid = oid;
row.objectType = objectType; // sub-entities can use it, now it's safe to set it
- transformer.storeRelatedEntities(row, schemaObject, jdbcSession);
+ rootMapping.storeRelatedEntities(row, schemaObject, jdbcSession);
jdbcSession.commit();
return oidString;
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java
deleted file mode 100644
index d63494567a3..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/ObjectTemplateSqlTransformer.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.qmodel;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType;
-
-public class ObjectTemplateSqlTransformer
- extends ObjectSqlTransformer {
-
- private final QObjectTemplateMapping mapping;
-
- public ObjectTemplateSqlTransformer(
- SqlTransformerSupport transformerSupport, QObjectTemplateMapping mapping) {
- super(transformerSupport, mapping);
- this.mapping = mapping;
- }
-
- @Override
- public void storeRelatedEntities(@NotNull MObject row,
- @NotNull ObjectTemplateType schemaObject, @NotNull JdbcSession jdbcSession) {
- super.storeRelatedEntities(row, schemaObject, jdbcSession);
-
- storeRefs(row, schemaObject.getIncludeRef(),
- QObjectReferenceMapping.INSTANCE_INCLUDE, jdbcSession);
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java
index 674c523ccd8..7bf93c339ee 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QObjectTemplateMapping.java
@@ -8,10 +8,13 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType.F_INCLUDE_REF;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType;
/**
@@ -22,13 +25,15 @@ public class QObjectTemplateMapping
public static final String DEFAULT_ALIAS_NAME = "ot";
- public static final QObjectTemplateMapping INSTANCE = new QObjectTemplateMapping();
+ public static QObjectTemplateMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QObjectTemplateMapping(repositoryContext);
+ }
- private QObjectTemplateMapping() {
+ private QObjectTemplateMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QObjectTemplate.TABLE_NAME, DEFAULT_ALIAS_NAME,
- ObjectTemplateType.class, QObjectTemplate.class);
+ ObjectTemplateType.class, QObjectTemplate.class, repositoryContext);
- addRefMapping(F_INCLUDE_REF, QObjectReferenceMapping.INSTANCE_INCLUDE);
+ addRefMapping(F_INCLUDE_REF, QObjectReferenceMapping.initForInclude(repositoryContext));
}
@Override
@@ -37,13 +42,16 @@ protected QObjectTemplate newAliasInstance(String alias) {
}
@Override
- public ObjectTemplateSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new ObjectTemplateSqlTransformer(transformerSupport, this);
+ public MObject newRowObject() {
+ return new MObject();
}
@Override
- public MObject newRowObject() {
- return new MObject();
+ public void storeRelatedEntities(@NotNull MObject row,
+ @NotNull ObjectTemplateType schemaObject, @NotNull JdbcSession jdbcSession) {
+ super.storeRelatedEntities(row, schemaObject, jdbcSession);
+
+ storeRefs(row, schemaObject.getIncludeRef(),
+ QObjectReferenceMapping.getForInclude(), jdbcSession);
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java
index b9b1c1ec9db..6345dca8ff4 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/QOwnedByMapping.java
@@ -6,7 +6,7 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
/**
* Marks mappings for {@link QOwnedBy} entities.
@@ -21,5 +21,5 @@ public interface QOwnedByMapping {
/** Returns a row with foreign key fields referencing the provided owner row. */
R newRowObject(OR ownerRow);
- TransformerForOwnedBy createTransformer(SqlTransformerSupport transformerSupport);
+ R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession);
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java
index f9f7a8fdf78..dc005cf2743 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleMappingMixin.java
@@ -1,5 +1,6 @@
package com.evolveum.midpoint.repo.sqale.qmodel;
+import java.util.Objects;
import java.util.function.BiFunction;
import javax.xml.namespace.QName;
@@ -65,6 +66,7 @@ default SqaleNestedMapping addNestedMapping(
/** Defines reference mapping for both query and modifications. */
default SqaleMappingMixin addRefMapping(
@NotNull QName itemName, @NotNull QReferenceMapping, ?, Q, R> referenceMapping) {
+ Objects.requireNonNull(referenceMapping, "referenceMapping");
addItemMapping(itemName, new SqaleItemSqlMapper<>(
ctx -> new RefTableItemFilterProcessor<>(ctx, referenceMapping),
ctx -> new RefTableItemDeltaProcessor<>(ctx, referenceMapping)));
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java
index 81b5cbdb34b..d5d836e7fb0 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTableMapping.java
@@ -6,29 +6,63 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+import java.util.function.Consumer;
import java.util.function.Function;
+import javax.xml.namespace.QName;
+import com.querydsl.core.Tuple;
import com.querydsl.core.types.dsl.*;
+import com.querydsl.sql.ColumnMetadata;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.delta.item.*;
import com.evolveum.midpoint.repo.sqale.filtering.RefItemFilterProcessor;
import com.evolveum.midpoint.repo.sqale.filtering.UriItemFilterProcessor;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleItemSqlMapper;
+import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObject;
+import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference;
+import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.filtering.item.EnumItemFilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.filtering.item.PolyStringItemFilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.filtering.item.SimpleItemFilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.filtering.item.TimestampItemFilterProcessor;
+import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMappingRegistry;
import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
import com.evolveum.midpoint.repo.sqlbase.querydsl.UuidPath;
+import com.evolveum.midpoint.schema.GetOperationOptions;
+import com.evolveum.midpoint.schema.SelectorOptions;
+import com.evolveum.midpoint.util.MiscUtil;
+import com.evolveum.midpoint.util.QNameUtil;
+import com.evolveum.midpoint.util.exception.SchemaException;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
+import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
/**
* Mapping superclass with common functions for {@link QObject} and non-objects (e.g. containers).
* See javadoc in {@link QueryTableMapping} for more.
*
+ * Mappings are often initialized using static `init*(repositoryContext)` methods, various
+ * suffixes are used for these reasons:
+ *
+ * * To differentiate various instances for the same mapping type, e.g. various references
+ * stored in separate tables;
+ * * or to avoid return type clash of the `init` method, even though they are static
+ * and technically independent Java meddles too much.
+ *
+ * Some subclasses (typically containers and refs) track their instances and avoid unnecessary
+ * instance creation for the same init method; the instance is available via matching `get*()`.
+ * Other subclasses (most objects) don't have `get()` methods but can be obtained using
+ * {@link QueryModelMappingRegistry#getByQueryType(Class)}, or by schema type (e.g. in tests).
+ *
* @param schema type
* @param type of entity path
* @param row type related to the {@link Q}
@@ -42,8 +76,13 @@ protected SqaleTableMapping(
@NotNull String tableName,
@NotNull String defaultAliasName,
@NotNull Class schemaType,
- @NotNull Class queryType) {
- super(tableName, defaultAliasName, schemaType, queryType);
+ @NotNull Class queryType,
+ @NotNull SqaleRepoContext repositoryContext) {
+ super(tableName, defaultAliasName, schemaType, queryType, repositoryContext);
+ }
+
+ public SqaleRepoContext repositoryContext() {
+ return (SqaleRepoContext) super.repositoryContext();
}
/**
@@ -80,7 +119,8 @@ public SqaleItemSqlMapper integerMapper(
* @param mapped schema type, see javadoc in {@link QueryTableMapping}
*/
@Override
- protected SqaleItemSqlMapper booleanMapper(Function rootToQueryItem) {
+ protected SqaleItemSqlMapper booleanMapper(
+ Function rootToQueryItem) {
return new SqaleItemSqlMapper<>(
ctx -> new SimpleItemFilterProcessor<>(ctx, rootToQueryItem),
ctx -> new SimpleItemDeltaProcessor<>(ctx, rootToQueryItem),
@@ -169,4 +209,147 @@ public > SqaleItemSqlMapper enumMapper(
ctx -> new EnumItemDeltaProcessor<>(ctx, rootToQueryItem),
rootToQueryItem);
}
+
+ @Override
+ public S toSchemaObject(R row) {
+ throw new UnsupportedOperationException("Use toSchemaObject(Tuple,...)");
+ }
+
+ /**
+ * Transforms row Tuple containing {@link R} under entity path and extension columns.
+ */
+ @Override
+ public S toSchemaObject(Tuple tuple, Q entityPath,
+ Collection> options)
+ throws SchemaException {
+ S schemaObject = toSchemaObject(tuple.get(entityPath));
+ processExtensionColumns(schemaObject, tuple, entityPath);
+ return schemaObject;
+ }
+
+ @SuppressWarnings("unused")
+ protected void processExtensionColumns(S schemaObject, Tuple tuple, Q entityPath) {
+ // empty by default, can be overridden
+ }
+
+ /**
+ * Returns {@link ObjectReferenceType} with specified oid, proper type based on
+ * {@link MObjectType} and, optionally, target name/description.
+ * Returns {@code null} if OID is null.
+ * Fails if OID is not null and {@code repoObjectType} is null.
+ */
+ @Nullable
+ protected ObjectReferenceType objectReferenceType(
+ @Nullable String oid, MObjectType repoObjectType, String targetName) {
+ if (oid == null) {
+ return null;
+ }
+ if (repoObjectType == null) {
+ throw new IllegalArgumentException(
+ "NULL object type provided for object reference with OID " + oid);
+ }
+
+ return new ObjectReferenceType()
+ .oid(oid)
+ .type(repositoryContext().schemaClassToQName(repoObjectType.getSchemaType()))
+ .description(targetName)
+ .targetName(targetName);
+ }
+
+ /**
+ * Trimming the value to the column size from column metadata (must be specified).
+ */
+ protected @Nullable String trim(
+ @Nullable String value, @NotNull ColumnMetadata columnMetadata) {
+ if (!columnMetadata.hasSize()) {
+ throw new IllegalArgumentException(
+ "trimString with column metadata without specified size: " + columnMetadata);
+ }
+ return MiscUtil.trimString(value, columnMetadata.getSize());
+ }
+
+ /**
+ * Returns ID for relation QName creating new {@link QUri} row in DB as needed.
+ * Relation is normalized before consulting the cache.
+ * Never returns null, returns default ID for configured default relation.
+ */
+ protected Integer processCacheableRelation(QName qName) {
+ return repositoryContext().processCacheableRelation(qName);
+ }
+
+ /** Returns ID for URI creating new cache row in DB as needed. */
+ protected Integer processCacheableUri(String uri) {
+ return uri != null
+ ? repositoryContext().processCacheableUri(uri)
+ : null;
+ }
+
+ /** Returns ID for URI creating new cache row in DB as needed. */
+ protected Integer processCacheableUri(QName qName) {
+ return qName != null
+ ? repositoryContext().processCacheableUri(QNameUtil.qNameToUri(qName))
+ : null;
+ }
+
+ /**
+ * Returns IDs as Integer array for URI strings creating new cache row in DB as needed.
+ * Returns null for null or empty list on input.
+ */
+ protected Integer[] processCacheableUris(List uris) {
+ if (uris == null || uris.isEmpty()) {
+ return null;
+ }
+ return uris.stream()
+ .map(uri -> processCacheableUri(uri))
+ .toArray(Integer[]::new);
+ }
+
+ protected @Nullable UUID oidToUUid(@Nullable String oid) {
+ return oid != null ? UUID.fromString(oid) : null;
+ }
+
+ protected MObjectType schemaTypeToObjectType(QName schemaType) {
+ return schemaType == null ? null :
+ MObjectType.fromSchemaType(repositoryContext().qNameToSchemaClass(schemaType));
+ }
+
+ protected void setPolyString(PolyStringType polyString,
+ Consumer origConsumer, Consumer normConsumer) {
+ if (polyString != null) {
+ origConsumer.accept(polyString.getOrig());
+ normConsumer.accept(polyString.getNorm());
+ }
+ }
+
+ protected void setReference(ObjectReferenceType ref,
+ Consumer targetOidConsumer, Consumer targetTypeConsumer,
+ Consumer relationIdConsumer) {
+ if (ref != null) {
+ targetOidConsumer.accept(oidToUUid(ref.getOid()));
+ targetTypeConsumer.accept(schemaTypeToObjectType(ref.getType()));
+ relationIdConsumer.accept(processCacheableRelation(ref.getRelation()));
+ }
+ }
+
+ protected , OR> void storeRefs(
+ @NotNull OR ownerRow, @NotNull List refs,
+ @NotNull QReferenceMapping, REF, OQ, OR> mapping, @NotNull JdbcSession jdbcSession) {
+ if (!refs.isEmpty()) {
+ refs.forEach(ref -> mapping.insert(ref, ownerRow, jdbcSession));
+ }
+ }
+
+ protected String[] arrayFor(List strings) {
+ if (strings == null || strings.isEmpty()) {
+ return null;
+ }
+ return strings.toArray(String[]::new);
+ }
+
+ /** Convenient insert shortcut when the row is fully populated. */
+ protected void insert(R row, JdbcSession jdbcSession) {
+ jdbcSession.newInsert(defaultAlias())
+ .populate(row)
+ .execute();
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java
deleted file mode 100644
index 9e86853cf9e..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/SqaleTransformerBase.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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.qmodel;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-import java.util.function.Consumer;
-import javax.xml.namespace.QName;
-
-import com.querydsl.core.Tuple;
-import com.querydsl.sql.ColumnMetadata;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.evolveum.midpoint.repo.sqale.SqaleTransformerSupport;
-import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri;
-import com.evolveum.midpoint.repo.sqale.qmodel.object.MObjectType;
-import com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference;
-import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping;
-import com.evolveum.midpoint.repo.sqale.qmodel.ref.ReferenceSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping;
-import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
-import com.evolveum.midpoint.schema.GetOperationOptions;
-import com.evolveum.midpoint.schema.SelectorOptions;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.util.QNameUtil;
-import com.evolveum.midpoint.util.exception.SchemaException;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
-import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
-
-/**
- * @param schema type
- * @param type of entity path
- * @param type of the row bean for the table
- */
-public abstract class SqaleTransformerBase, R>
- implements SqlTransformer {
-
- protected final Logger logger = LoggerFactory.getLogger(getClass());
-
- protected final SqaleTransformerSupport transformerSupport;
-
- /**
- * Constructor uses {@link SqlTransformerSupport} type even when it really is
- * {@link SqaleTransformerSupport}, but this way we can cast it just once here; otherwise cast
- * would be needed in each implementation of {@link QueryTableMapping#createTransformer)}.
- * (Alternative is to parametrize {@link QueryTableMapping} with various {@link SqlTransformer}
- * types which is not convenient at all. This little downcast is low price to pay.)
- */
- protected SqaleTransformerBase(SqlTransformerSupport transformerSupport) {
- this.transformerSupport = (SqaleTransformerSupport) transformerSupport;
- }
-
- protected abstract QueryTableMapping mapping();
-
- @Override
- public S toSchemaObject(R row) {
- throw new UnsupportedOperationException("Use toSchemaObject(Tuple,...)");
- }
-
- /**
- * Transforms row Tuple containing {@link R} under entity path and extension columns.
- */
- @Override
- public S toSchemaObject(Tuple tuple, Q entityPath,
- Collection> options)
- throws SchemaException {
- S schemaObject = toSchemaObject(tuple.get(entityPath));
- processExtensionColumns(schemaObject, tuple, entityPath);
- return schemaObject;
- }
-
- @SuppressWarnings("unused")
- protected void processExtensionColumns(S schemaObject, Tuple tuple, Q entityPath) {
- // empty by default, can be overridden
- }
-
- /**
- * Returns {@link ObjectReferenceType} with specified oid, proper type based on
- * {@link MObjectType} and, optionally, target name/description.
- * Returns {@code null} if OID is null.
- * Fails if OID is not null and {@code repoObjectType} is null.
- */
- @Nullable
- protected ObjectReferenceType objectReferenceType(
- @Nullable String oid, MObjectType repoObjectType, String targetName) {
- if (oid == null) {
- return null;
- }
- if (repoObjectType == null) {
- throw new IllegalArgumentException(
- "NULL object type provided for object reference with OID " + oid);
- }
-
- return new ObjectReferenceType()
- .oid(oid)
- .type(transformerSupport.schemaClassToQName(repoObjectType.getSchemaType()))
- .description(targetName)
- .targetName(targetName);
- }
-
- /**
- * Trimming the value to the column size from column metadata (must be specified).
- */
- protected @Nullable String trim(
- @Nullable String value, @NotNull ColumnMetadata columnMetadata) {
- if (!columnMetadata.hasSize()) {
- throw new IllegalArgumentException(
- "trimString with column metadata without specified size: " + columnMetadata);
- }
- return MiscUtil.trimString(value, columnMetadata.getSize());
- }
-
- protected @NotNull Integer searchCachedRelationId(QName qName) {
- return transformerSupport.searchCachedRelationId(qName);
- }
-
- /** Returns ID for cached URI without going to the database. */
- protected Integer resolveUriToId(String uri) {
- return transformerSupport.resolveUriToId(uri);
- }
-
- /**
- * Returns ID for relation QName creating new {@link QUri} row in DB as needed.
- * Relation is normalized before consulting the cache.
- * Never returns null, returns default ID for configured default relation.
- */
- protected Integer processCacheableRelation(QName qName) {
- return transformerSupport.processCacheableRelation(qName);
- }
-
- /** Returns ID for URI creating new cache row in DB as needed. */
- protected Integer processCacheableUri(String uri) {
- return uri != null
- ? transformerSupport.processCacheableUri(uri)
- : null;
- }
-
- /** Returns ID for URI creating new cache row in DB as needed. */
- protected Integer processCacheableUri(QName qName) {
- return qName != null
- ? transformerSupport.processCacheableUri(QNameUtil.qNameToUri(qName))
- : null;
- }
-
- /**
- * Returns IDs as Integer array for URI strings creating new cache row in DB as needed.
- * Returns null for null or empty list on input.
- */
- protected Integer[] processCacheableUris(List uris) {
- if (uris == null || uris.isEmpty()) {
- return null;
- }
- return uris.stream()
- .map(uri -> processCacheableUri(uri))
- .toArray(Integer[]::new);
- }
-
- protected @Nullable UUID oidToUUid(@Nullable String oid) {
- return oid != null ? UUID.fromString(oid) : null;
- }
-
- protected MObjectType schemaTypeToObjectType(QName schemaType) {
- return schemaType == null ? null :
- MObjectType.fromSchemaType(
- transformerSupport.qNameToSchemaClass(schemaType));
- }
-
- protected void setPolyString(PolyStringType polyString,
- Consumer origConsumer, Consumer normConsumer) {
- if (polyString != null) {
- origConsumer.accept(polyString.getOrig());
- normConsumer.accept(polyString.getNorm());
- }
- }
-
- protected void setReference(ObjectReferenceType ref,
- Consumer targetOidConsumer, Consumer targetTypeConsumer,
- Consumer relationIdConsumer) {
- if (ref != null) {
- targetOidConsumer.accept(oidToUUid(ref.getOid()));
- targetTypeConsumer.accept(schemaTypeToObjectType(ref.getType()));
- relationIdConsumer.accept(processCacheableRelation(ref.getRelation()));
- }
- }
-
- protected , OR> void storeRefs(
- @NotNull OR ownerRow, @NotNull List refs,
- @NotNull QReferenceMapping, REF, OQ, OR> mapping, @NotNull JdbcSession jdbcSession) {
- if (!refs.isEmpty()) {
- ReferenceSqlTransformer, REF, OR> transformer =
- mapping.createTransformer(transformerSupport);
- refs.forEach(ref -> transformer.insert(ref, ownerRow, jdbcSession));
- }
- }
-
- protected String[] arrayFor(List strings) {
- if (strings == null || strings.isEmpty()) {
- return null;
- }
- return strings.toArray(String[]::new);
- }
-
- /** Convenient insert shortcut when the row is fully populated. */
- protected void insert(R row, JdbcSession jdbcSession) {
- jdbcSession.newInsert(mapping().defaultAlias())
- .populate(row)
- .execute();
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java
deleted file mode 100644
index b760c78d907..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/TransformerForOwnedBy.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.qmodel;
-
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-
-/**
- * Declares capability to insert row for the provided schema object owned by provided row.
- *
- * @param schema type
- * @param target type of the transformation, a row bean
- * @param row type of the reference owner
- */
-public interface TransformerForOwnedBy {
-
- /** Contract for insertion of row of type {@link R} owned by {@link OR}. */
- R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession);
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java
deleted file mode 100644
index 52570a81a0d..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/AccessCertificationDefinitionSqlTransformer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.qmodel.accesscert;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType;
-
-public class AccessCertificationDefinitionSqlTransformer
- extends ObjectSqlTransformer {
-
- public AccessCertificationDefinitionSqlTransformer(
- SqlTransformerSupport transformerSupport,
- QAccessCertificationDefinitionMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public @NotNull MAccessCertificationDefinition toRowObjectWithoutFullObject(
- AccessCertificationDefinitionType schemaObject, JdbcSession jdbcSession) {
- MAccessCertificationDefinition row =
- super.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
-
- row.handlerUriId = processCacheableUri(schemaObject.getHandlerUri());
- row.lastCampaignStartedTimestamp =
- MiscUtil.asInstant(schemaObject.getLastCampaignStartedTimestamp());
- row.lastCampaignClosedTimestamp =
- MiscUtil.asInstant(schemaObject.getLastCampaignClosedTimestamp());
- setReference(schemaObject.getOwnerRef(),
- o -> row.ownerRefTargetOid = o,
- t -> row.ownerRefTargetType = t,
- r -> row.ownerRefRelationId = r);
-
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java
index e302547d70f..0c782c0d664 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/accesscert/QAccessCertificationDefinitionMapping.java
@@ -8,8 +8,12 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractAccessCertificationDefinitionType.*;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationDefinitionType;
/**
@@ -22,12 +26,15 @@ public class QAccessCertificationDefinitionMapping
public static final String DEFAULT_ALIAS_NAME = "acd";
- public static final QAccessCertificationDefinitionMapping INSTANCE =
- new QAccessCertificationDefinitionMapping();
+ public static QAccessCertificationDefinitionMapping init(
+ @NotNull SqaleRepoContext repositoryContext) {
+ return new QAccessCertificationDefinitionMapping(repositoryContext);
+ }
- private QAccessCertificationDefinitionMapping() {
+ private QAccessCertificationDefinitionMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QAccessCertificationDefinition.TABLE_NAME, DEFAULT_ALIAS_NAME,
- AccessCertificationDefinitionType.class, QAccessCertificationDefinition.class);
+ AccessCertificationDefinitionType.class, QAccessCertificationDefinition.class,
+ repositoryContext);
addItemMapping(F_HANDLER_URI, uriMapper(q -> q.handlerUriId));
addItemMapping(F_LAST_CAMPAIGN_STARTED_TIMESTAMP,
@@ -46,12 +53,26 @@ protected QAccessCertificationDefinition newAliasInstance(String alias) {
}
@Override
- public AccessCertificationDefinitionSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new AccessCertificationDefinitionSqlTransformer(transformerSupport, this);
+ public MAccessCertificationDefinition newRowObject() {
+ return new MAccessCertificationDefinition();
}
@Override
- public MAccessCertificationDefinition newRowObject() {
- return new MAccessCertificationDefinition();
+ public @NotNull MAccessCertificationDefinition toRowObjectWithoutFullObject(
+ AccessCertificationDefinitionType schemaObject, JdbcSession jdbcSession) {
+ MAccessCertificationDefinition row =
+ super.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
+
+ row.handlerUriId = processCacheableUri(schemaObject.getHandlerUri());
+ row.lastCampaignStartedTimestamp =
+ MiscUtil.asInstant(schemaObject.getLastCampaignStartedTimestamp());
+ row.lastCampaignClosedTimestamp =
+ MiscUtil.asInstant(schemaObject.getLastCampaignClosedTimestamp());
+ setReference(schemaObject.getOwnerRef(),
+ o -> row.ownerRefTargetOid = o,
+ t -> row.ownerRefTargetType = t,
+ r -> row.ownerRefRelationId = r);
+
+ return row;
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java
deleted file mode 100644
index e69e2d1fab4..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/AssignmentSqlTransformer.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.qmodel.assignment;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ContainerSqlTransformer;
-import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType;
-
-public class AssignmentSqlTransformer
- extends ContainerSqlTransformer, MAssignment, OR> {
-
- public AssignmentSqlTransformer(
- SqlTransformerSupport transformerSupport, QAssignmentMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- // about duplication see the comment in ObjectSqlTransformer.toRowObjectWithoutFullObject
- @SuppressWarnings("DuplicatedCode")
- @Override
- public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jdbcSession) {
- MAssignment row = initRowObject(assignment, ownerRow);
-
- row.ownerType = ownerRow.objectType;
- row.lifecycleState = assignment.getLifecycleState();
- row.orderValue = assignment.getOrder();
- setReference(assignment.getOrgRef(),
- o -> row.orgRefTargetOid = o,
- t -> row.orgRefTargetType = t,
- r -> row.orgRefRelationId = r);
- setReference(assignment.getTargetRef(),
- o -> row.targetRefTargetOid = o,
- t -> row.targetRefTargetType = t,
- r -> row.targetRefRelationId = r);
- setReference(assignment.getTenantRef(),
- o -> row.tenantRefTargetOid = o,
- t -> row.tenantRefTargetType = t,
- r -> row.tenantRefRelationId = r);
-
- // TODO no idea how to do this yet, somehow related to RAssignment.extension
-// row.extId = assignment.getExtension()...id?;
-// row.extOid =;
- row.policySituations = processCacheableUris(assignment.getPolicySituation());
- // TODO extensions stored inline (JSON)
-
- ConstructionType construction = assignment.getConstruction();
- if (construction != null) {
- setReference(construction.getResourceRef(),
- o -> row.resourceRefTargetOid = o,
- t -> row.resourceRefTargetType = t,
- r -> row.resourceRefRelationId = r);
- }
-
- ActivationType activation = assignment.getActivation();
- if (activation != null) {
- row.administrativeStatus = activation.getAdministrativeStatus();
- row.effectiveStatus = activation.getEffectiveStatus();
- row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp());
- row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp());
- row.disableReason = activation.getDisableReason();
- row.validityStatus = activation.getValidityStatus();
- row.validFrom = MiscUtil.asInstant(activation.getValidFrom());
- row.validTo = MiscUtil.asInstant(activation.getValidTo());
- row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp());
- row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp());
- }
-
- MetadataType metadata = assignment.getMetadata();
- if (metadata != null) {
- setReference(metadata.getCreatorRef(),
- o -> row.creatorRefTargetOid = o,
- t -> row.creatorRefTargetType = t,
- r -> row.creatorRefRelationId = r);
- row.createChannelId = processCacheableUri(metadata.getCreateChannel());
- row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp());
-
- setReference(metadata.getModifierRef(),
- o -> row.modifierRefTargetOid = o,
- t -> row.modifierRefTargetType = t,
- r -> row.modifierRefRelationId = r);
- row.modifyChannelId = processCacheableUri(metadata.getModifyChannel());
- row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp());
- }
-
- // insert before treating sub-entities
- insert(row, jdbcSession);
-
- if (metadata != null) {
- storeRefs(row, metadata.getCreateApproverRef(),
- QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER, jdbcSession);
- storeRefs(row, metadata.getModifyApproverRef(),
- QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_MODIFY_APPROVER, jdbcSession);
- }
-
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java
index 35efcf9ae88..b66cda08b24 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentMapping.java
@@ -8,10 +8,16 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType.*;
+import java.util.Objects;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
+import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainerType;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
-import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType;
@@ -19,6 +25,10 @@
/**
* Mapping between {@link QAssignment} and {@link AssignmentType}.
+ * There are separate instances for assignments and inducements and the instance also knows
+ * the {@link MAssignment#containerType} it should set.
+ * Only the instance for assignments is registered for queries as there is no way to distinguish
+ * between assignments and inducements when searching containers in the Query API anyway.
*
* @param type of the owner row
*/
@@ -27,13 +37,50 @@ public class QAssignmentMapping
public static final String DEFAULT_ALIAS_NAME = "a";
- public static final QAssignmentMapping INSTANCE = new QAssignmentMapping<>();
+ /** Default assignment mapping instance, for queries it works for inducements too. */
+ private static QAssignmentMapping> instanceAssignment;
+
+ /** Inducement mapping instance, this must be used for inserting inducements. */
+ private static QAssignmentMapping> instanceInducement;
+
+ public static QAssignmentMapping
+ initAssignment(@NotNull SqaleRepoContext repositoryContext) {
+ if (instanceAssignment == null) {
+ instanceAssignment = new QAssignmentMapping<>(
+ MContainerType.ASSIGNMENT, repositoryContext);
+ }
+ return getAssignment();
+ }
+
+ public static QAssignmentMapping getAssignment() {
+ //noinspection unchecked
+ return (QAssignmentMapping) Objects.requireNonNull(instanceAssignment);
+ }
+
+ public static QAssignmentMapping
+ initInducement(@NotNull SqaleRepoContext repositoryContext) {
+ if (instanceInducement == null) {
+ instanceInducement = new QAssignmentMapping<>(
+ MContainerType.INDUCEMENT, repositoryContext);
+ }
+ return getInducement();
+ }
+
+ public static QAssignmentMapping getInducement() {
+ //noinspection unchecked
+ return (QAssignmentMapping) Objects.requireNonNull(instanceInducement);
+ }
+
+ private final MContainerType containerType;
// We can't declare Class>.class, so we cheat a bit.
@SuppressWarnings({ "unchecked", "rawtypes" })
- private QAssignmentMapping() {
+ private QAssignmentMapping(
+ @NotNull MContainerType containerType,
+ @NotNull SqaleRepoContext repositoryContext) {
super(QAssignment.TABLE_NAME, DEFAULT_ALIAS_NAME,
- AssignmentType.class, (Class) QAssignment.class);
+ AssignmentType.class, (Class) QAssignment.class, repositoryContext);
+ this.containerType = containerType;
// TODO OWNER_TYPE is new thing and can help avoid join to concrete object table
// But this will likely require special treatment/heuristic.
@@ -96,17 +143,12 @@ private QAssignmentMapping() {
uriMapper(q -> q.modifyChannelId))
.addItemMapping(MetadataType.F_MODIFY_TIMESTAMP,
timestampMapper(q -> q.modifyTimestamp))
- .addRefMapping(MetadataType.F_CREATE_APPROVER_REF, referenceMapping(
- QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_CREATE_APPROVER))
- .addRefMapping(MetadataType.F_MODIFY_APPROVER_REF, referenceMapping(
- QAssignmentReferenceMapping.INSTANCE_ASSIGNMENT_MODIFY_APPROVER));
- }
-
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- private QReferenceMapping, ?, QAssignment, MAssignment> referenceMapping(
- QAssignmentReferenceMapping> referenceMapping) {
- //noinspection unchecked
- return (QAssignmentReferenceMapping) referenceMapping;
+ .addRefMapping(MetadataType.F_CREATE_APPROVER_REF,
+ QAssignmentReferenceMapping.initForAssignmentCreateApprover(
+ repositoryContext))
+ .addRefMapping(MetadataType.F_MODIFY_APPROVER_REF,
+ QAssignmentReferenceMapping.initForAssignmentModifyApprover(
+ repositoryContext));
}
@Override
@@ -114,14 +156,11 @@ protected QAssignment newAliasInstance(String alias) {
return new QAssignment<>(alias);
}
- @Override
- public AssignmentSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new AssignmentSqlTransformer<>(transformerSupport, this);
- }
-
@Override
public MAssignment newRowObject() {
- return new MAssignment();
+ MAssignment row = new MAssignment();
+ row.containerType = this.containerType;
+ return row;
}
@Override
@@ -130,4 +169,84 @@ public MAssignment newRowObject(OR ownerRow) {
row.ownerOid = ownerRow.oid;
return row;
}
+
+ // about duplication see the comment in QObjectMapping.toRowObjectWithoutFullObject
+ @SuppressWarnings("DuplicatedCode")
+ @Override
+ public MAssignment insert(AssignmentType assignment, OR ownerRow, JdbcSession jdbcSession) {
+ MAssignment row = initRowObject(assignment, ownerRow);
+
+ row.ownerType = ownerRow.objectType;
+ row.lifecycleState = assignment.getLifecycleState();
+ row.orderValue = assignment.getOrder();
+ setReference(assignment.getOrgRef(),
+ o -> row.orgRefTargetOid = o,
+ t -> row.orgRefTargetType = t,
+ r -> row.orgRefRelationId = r);
+ setReference(assignment.getTargetRef(),
+ o -> row.targetRefTargetOid = o,
+ t -> row.targetRefTargetType = t,
+ r -> row.targetRefRelationId = r);
+ setReference(assignment.getTenantRef(),
+ o -> row.tenantRefTargetOid = o,
+ t -> row.tenantRefTargetType = t,
+ r -> row.tenantRefRelationId = r);
+
+ // TODO no idea how to do this yet, somehow related to RAssignment.extension
+// row.extId = assignment.getExtension()...id?;
+// row.extOid =;
+ row.policySituations = processCacheableUris(assignment.getPolicySituation());
+ // TODO extensions stored inline (JSON)
+
+ ConstructionType construction = assignment.getConstruction();
+ if (construction != null) {
+ setReference(construction.getResourceRef(),
+ o -> row.resourceRefTargetOid = o,
+ t -> row.resourceRefTargetType = t,
+ r -> row.resourceRefRelationId = r);
+ }
+
+ ActivationType activation = assignment.getActivation();
+ if (activation != null) {
+ row.administrativeStatus = activation.getAdministrativeStatus();
+ row.effectiveStatus = activation.getEffectiveStatus();
+ row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp());
+ row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp());
+ row.disableReason = activation.getDisableReason();
+ row.validityStatus = activation.getValidityStatus();
+ row.validFrom = MiscUtil.asInstant(activation.getValidFrom());
+ row.validTo = MiscUtil.asInstant(activation.getValidTo());
+ row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp());
+ row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp());
+ }
+
+ MetadataType metadata = assignment.getMetadata();
+ if (metadata != null) {
+ setReference(metadata.getCreatorRef(),
+ o -> row.creatorRefTargetOid = o,
+ t -> row.creatorRefTargetType = t,
+ r -> row.creatorRefRelationId = r);
+ row.createChannelId = processCacheableUri(metadata.getCreateChannel());
+ row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp());
+
+ setReference(metadata.getModifierRef(),
+ o -> row.modifierRefTargetOid = o,
+ t -> row.modifierRefTargetType = t,
+ r -> row.modifierRefRelationId = r);
+ row.modifyChannelId = processCacheableUri(metadata.getModifyChannel());
+ row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp());
+ }
+
+ // insert before treating sub-entities
+ insert(row, jdbcSession);
+
+ if (metadata != null) {
+ storeRefs(row, metadata.getCreateApproverRef(),
+ QAssignmentReferenceMapping.getForAssignmentCreateApprover(), jdbcSession);
+ storeRefs(row, metadata.getModifyApproverRef(),
+ QAssignmentReferenceMapping.getForAssignmentModifyApprover(), jdbcSession);
+ }
+
+ return row;
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java
index 56fe38d3f24..a434fd16c0a 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/assignment/QAssignmentReferenceMapping.java
@@ -6,31 +6,68 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel.assignment;
+import java.util.Objects;
import java.util.function.BiFunction;
import com.querydsl.core.types.Predicate;
+import org.jetbrains.annotations.NotNull;
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.MObject;
-import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReference;
import com.evolveum.midpoint.repo.sqale.qmodel.ref.QReferenceMapping;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
/**
- * Mapping between {@link QObjectReference} and {@link ObjectReferenceType}.
- * The mapping is the same for all subtypes, see different `INSTANCE_*` constants below.
+ * Mapping between {@link QAssignmentReference} and {@link ObjectReferenceType}.
+ * The mapping is the same for all subtypes, see various static `get*()` methods below.
+ * Both mapping instances are initialized (`init*()` methods) in {@link QAssignmentMapping}.
+ * Init methods can be called multiple times, only one instance for each sub-tables is created.
*
* @param type of the row (M-bean) of the assignment owner
*/
public class QAssignmentReferenceMapping
extends QReferenceMapping, MAssignment> {
- public static final QAssignmentReferenceMapping> INSTANCE_ASSIGNMENT_CREATE_APPROVER =
- new QAssignmentReferenceMapping<>("m_assignment_ref_create_approver", "arefca");
- public static final QAssignmentReferenceMapping> INSTANCE_ASSIGNMENT_MODIFY_APPROVER =
- new QAssignmentReferenceMapping<>("m_assignment_ref_create_approver", "arefma");
+ private static QAssignmentReferenceMapping> instanceAssignmentCreateApprover;
+ private static QAssignmentReferenceMapping> instanceAssignmentModifyApprover;
- private QAssignmentReferenceMapping(String tableName, String defaultAliasName) {
- super(tableName, defaultAliasName, QAssignmentReference.class);
+ public static QAssignmentReferenceMapping
+ initForAssignmentCreateApprover(@NotNull SqaleRepoContext repositoryContext) {
+ if (instanceAssignmentCreateApprover == null) {
+ instanceAssignmentCreateApprover = new QAssignmentReferenceMapping<>(
+ "m_assignment_ref_create_approver", "arefca", repositoryContext);
+ }
+ return getForAssignmentCreateApprover();
+ }
+
+ public static QAssignmentReferenceMapping
+ getForAssignmentCreateApprover() {
+ //noinspection unchecked
+ return (QAssignmentReferenceMapping)
+ Objects.requireNonNull(instanceAssignmentCreateApprover);
+ }
+
+ public static QAssignmentReferenceMapping
+ initForAssignmentModifyApprover(@NotNull SqaleRepoContext repositoryContext) {
+ if (instanceAssignmentModifyApprover == null) {
+ instanceAssignmentModifyApprover = new QAssignmentReferenceMapping<>(
+ "m_assignment_ref_modify_approver", "arefma", repositoryContext);
+ }
+ return getForAssignmentModifyApprover();
+ }
+
+ public static QAssignmentReferenceMapping
+ getForAssignmentModifyApprover() {
+ //noinspection unchecked
+ return (QAssignmentReferenceMapping)
+ Objects.requireNonNull(instanceAssignmentModifyApprover);
+ }
+
+ private QAssignmentReferenceMapping(
+ String tableName,
+ String defaultAliasName,
+ @NotNull SqaleRepoContext repositoryContext) {
+ super(tableName, defaultAliasName, QAssignmentReference.class, repositoryContext);
// assignmentCid probably can't be mapped directly
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java
index 92d6f162b04..9ee84f7589a 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/cases/QCaseMapping.java
@@ -8,9 +8,10 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType.*;
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseType;
/**
@@ -21,11 +22,13 @@ public class QCaseMapping
public static final String DEFAULT_ALIAS_NAME = "cs";
- public static final QCaseMapping INSTANCE = new QCaseMapping();
+ public static QCaseMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QCaseMapping(repositoryContext);
+ }
- private QCaseMapping() {
+ private QCaseMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QCase.TABLE_NAME, DEFAULT_ALIAS_NAME,
- CaseType.class, QCase.class);
+ CaseType.class, QCase.class, repositoryContext);
addItemMapping(F_STATE, stringMapper(q -> q.state));
addItemMapping(F_CLOSE_TIMESTAMP, timestampMapper(q -> q.closeTimestamp));
@@ -52,15 +55,10 @@ protected QCase newAliasInstance(String alias) {
return new QCase(alias);
}
- @Override
- public ObjectSqlTransformer
- createTransformer(SqlTransformerSupport transformerSupport) {
- // no special class needed, no additional columns
- return new ObjectSqlTransformer<>(transformerSupport, this);
- }
-
@Override
public MCase newRowObject() {
return new MCase();
}
+
+ // TODO transformation code
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java
index 793303094a8..b78cd02cdc5 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/common/QContainerMapping.java
@@ -9,10 +9,10 @@
import org.jetbrains.annotations.NotNull;
import com.evolveum.midpoint.prism.Containerable;
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.QOwnedByMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping;
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ContainerSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
/**
* Mapping between {@link QContainer} and {@link Containerable}.
@@ -28,17 +28,20 @@ public class QContainerMapping, MContainer, Object> INSTANCE =
- new QContainerMapping<>(QContainer.TABLE_NAME, DEFAULT_ALIAS_NAME,
- Containerable.class, QContainer.CLASS);
+ public static QContainerMapping, ?, ?, ?> initContainerMapping(@NotNull SqaleRepoContext repositoryContext) {
+ return new QContainerMapping<>(
+ QContainer.TABLE_NAME, DEFAULT_ALIAS_NAME,
+ Containerable.class, QContainer.CLASS,
+ repositoryContext);
+ }
protected QContainerMapping(
@NotNull String tableName,
@NotNull String defaultAliasName,
@NotNull Class schemaType,
- @NotNull Class queryType) {
- super(tableName, defaultAliasName, schemaType, queryType);
+ @NotNull Class queryType,
+ @NotNull SqaleRepoContext repositoryContext) {
+ super(tableName, defaultAliasName, schemaType, queryType, repositoryContext);
// CID is not mapped directly, it is used by path resolver elsewhere
}
@@ -55,15 +58,24 @@ public R newRowObject(OR ownerRow) {
"Container bean creation for owner row called on abstract container mapping");
}
- @Override
- public ContainerSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new ContainerSqlTransformer<>(transformerSupport, this);
- }
-
@Override
public R newRowObject() {
//noinspection unchecked
return (R) new MContainer();
}
+
+ /**
+ * This creates the right type of object and fills in the base {@link MContainer} attributes.
+ */
+ public R initRowObject(S schemaObject, OR ownerRow) {
+ R row = newRowObject(ownerRow);
+ row.cid = schemaObject.asPrismContainerValue().getId();
+ // containerType is generated in DB, must be left null!
+ return row;
+ }
+
+ @Override
+ public R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession) {
+ throw new UnsupportedOperationException("insert not implemented in the subclass");
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java
deleted file mode 100644
index 10479473c4e..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorHostSqlTransformer.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.qmodel.connector;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType;
-
-public class ConnectorHostSqlTransformer
- extends ObjectSqlTransformer {
-
- public ConnectorHostSqlTransformer(
- SqlTransformerSupport transformerSupport, QConnectorHostMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public @NotNull MConnectorHost toRowObjectWithoutFullObject(
- ConnectorHostType schemaObject, JdbcSession jdbcSession) {
- MConnectorHost row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
-
- row.hostname = schemaObject.getHostname();
- row.port = schemaObject.getPort();
-
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java
deleted file mode 100644
index 8d36432ed34..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/ConnectorSqlTransformer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.qmodel.connector;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType;
-
-public class ConnectorSqlTransformer
- extends ObjectSqlTransformer {
-
- public ConnectorSqlTransformer(
- SqlTransformerSupport transformerSupport, QConnectorMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public @NotNull MConnector toRowObjectWithoutFullObject(
- ConnectorType schemaObject, JdbcSession jdbcSession) {
- MConnector row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
-
- row.connectorBundle = schemaObject.getConnectorBundle();
- row.connectorType = schemaObject.getConnectorType();
- row.connectorVersion = schemaObject.getConnectorVersion();
- row.frameworkId = processCacheableUri(schemaObject.getFramework());
-
- setReference(schemaObject.getConnectorHostRef(),
- o -> row.connectorHostRefTargetOid = o,
- t -> row.connectorHostRefTargetType = t,
- r -> row.connectorHostRefRelationId = r);
-
- row.targetSystemTypes = arrayFor(schemaObject.getTargetSystemType());
-
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java
index 2eb116abebf..ccf8474a3a6 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorHostMapping.java
@@ -9,8 +9,11 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType.F_HOSTNAME;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType.F_PORT;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType;
/**
@@ -21,11 +24,13 @@ public class QConnectorHostMapping
public static final String DEFAULT_ALIAS_NAME = "conh";
- public static final QConnectorHostMapping INSTANCE = new QConnectorHostMapping();
+ public static QConnectorHostMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QConnectorHostMapping(repositoryContext);
+ }
- private QConnectorHostMapping() {
+ private QConnectorHostMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QConnectorHost.TABLE_NAME, DEFAULT_ALIAS_NAME,
- ConnectorHostType.class, QConnectorHost.class);
+ ConnectorHostType.class, QConnectorHost.class, repositoryContext);
addItemMapping(F_HOSTNAME, stringMapper(q -> q.hostname));
addItemMapping(F_PORT, stringMapper(q -> q.port));
@@ -37,12 +42,18 @@ protected QConnectorHost newAliasInstance(String alias) {
}
@Override
- public ConnectorHostSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new ConnectorHostSqlTransformer(transformerSupport, this);
+ public MConnectorHost newRowObject() {
+ return new MConnectorHost();
}
@Override
- public MConnectorHost newRowObject() {
- return new MConnectorHost();
+ public @NotNull MConnectorHost toRowObjectWithoutFullObject(
+ ConnectorHostType schemaObject, JdbcSession jdbcSession) {
+ MConnectorHost row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
+
+ row.hostname = schemaObject.getHostname();
+ row.port = schemaObject.getPort();
+
+ return row;
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java
index 2b550bb8fc5..aebdedbbd45 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/connector/QConnectorMapping.java
@@ -8,8 +8,11 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType.*;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType;
/**
@@ -20,10 +23,13 @@ public class QConnectorMapping
public static final String DEFAULT_ALIAS_NAME = "con";
- public static final QConnectorMapping INSTANCE = new QConnectorMapping();
+ public static QConnectorMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QConnectorMapping(repositoryContext);
+ }
- private QConnectorMapping() {
- super(QConnector.TABLE_NAME, DEFAULT_ALIAS_NAME, ConnectorType.class, QConnector.class);
+ private QConnectorMapping(@NotNull SqaleRepoContext repositoryContext) {
+ super(QConnector.TABLE_NAME, DEFAULT_ALIAS_NAME,
+ ConnectorType.class, QConnector.class, repositoryContext);
addItemMapping(F_CONNECTOR_BUNDLE, stringMapper(q -> q.connectorBundle));
addItemMapping(F_CONNECTOR_TYPE, stringMapper(q -> q.connectorType));
@@ -43,12 +49,27 @@ protected QConnector newAliasInstance(String alias) {
}
@Override
- public ConnectorSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new ConnectorSqlTransformer(transformerSupport, this);
+ public MConnector newRowObject() {
+ return new MConnector();
}
@Override
- public MConnector newRowObject() {
- return new MConnector();
+ public @NotNull MConnector toRowObjectWithoutFullObject(
+ ConnectorType schemaObject, JdbcSession jdbcSession) {
+ MConnector row = super.toRowObjectWithoutFullObject(schemaObject, jdbcSession);
+
+ row.connectorBundle = schemaObject.getConnectorBundle();
+ row.connectorType = schemaObject.getConnectorType();
+ row.connectorVersion = schemaObject.getConnectorVersion();
+ row.frameworkId = processCacheableUri(schemaObject.getFramework());
+
+ setReference(schemaObject.getConnectorHostRef(),
+ o -> row.connectorHostRefTargetOid = o,
+ t -> row.connectorHostRefTargetType = t,
+ r -> row.connectorHostRefRelationId = r);
+
+ row.targetSystemTypes = arrayFor(schemaObject.getTargetSystemType());
+
+ return row;
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java
deleted file mode 100644
index 266b2e10789..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/FocusSqlTransformer.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.qmodel.focus;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
-
-public class FocusSqlTransformer, R extends MFocus>
- extends ObjectSqlTransformer {
-
- private final QFocusMapping mapping;
-
- public FocusSqlTransformer(
- SqlTransformerSupport transformerSupport, QFocusMapping mapping) {
- super(transformerSupport, mapping);
- this.mapping = mapping;
- }
-
- @SuppressWarnings("DuplicatedCode") // activation code duplicated with assignment
- @Override
- public @NotNull R toRowObjectWithoutFullObject(S focus, JdbcSession jdbcSession) {
- R row = super.toRowObjectWithoutFullObject(focus, jdbcSession);
-
- row.costCenter = focus.getCostCenter();
- row.emailAddress = focus.getEmailAddress();
- row.photo = focus.getJpegPhoto();
- row.locale = focus.getLocale();
- setPolyString(focus.getLocality(), o -> row.localityOrig = o, n -> row.localityNorm = n);
- row.preferredLanguage = focus.getPreferredLanguage();
- row.telephoneNumber = focus.getTelephoneNumber();
- row.timezone = focus.getTimezone();
-
- // credential/password/metadata (sorry for nesting, but the gets may not be so cheap)
- CredentialsType credentials = focus.getCredentials();
- if (credentials != null) {
- PasswordType password = credentials.getPassword();
- if (password != null) {
- MetadataType passwordMetadata = password.getMetadata();
- if (passwordMetadata != null) {
- row.passwordCreateTimestamp =
- MiscUtil.asInstant(passwordMetadata.getCreateTimestamp());
- row.passwordModifyTimestamp =
- MiscUtil.asInstant(passwordMetadata.getModifyTimestamp());
- }
- }
- }
-
- // activation
- ActivationType activation = focus.getActivation();
- if (activation != null) {
- row.administrativeStatus = activation.getAdministrativeStatus();
- row.effectiveStatus = activation.getEffectiveStatus();
- row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp());
- row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp());
- row.disableReason = activation.getDisableReason();
- row.validityStatus = activation.getValidityStatus();
- row.validFrom = MiscUtil.asInstant(activation.getValidFrom());
- row.validTo = MiscUtil.asInstant(activation.getValidTo());
- row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp());
- row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp());
- row.lockoutStatus = activation.getLockoutStatus();
- }
-
- return row;
- }
-
- @Override
- public void storeRelatedEntities(
- @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) {
- super.storeRelatedEntities(row, schemaObject, jdbcSession);
-
- storeRefs(row, schemaObject.getLinkRef(),
- mapping.projectionReferenceMapping(), jdbcSession);
- storeRefs(row, schemaObject.getPersonaRef(),
- mapping.personaReferenceMapping(), jdbcSession);
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java
deleted file mode 100644
index 8bfc9143b02..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/GenericObjectSqlTransformer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.qmodel.focus;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType;
-
-public class GenericObjectSqlTransformer
- extends FocusSqlTransformer {
-
- public GenericObjectSqlTransformer(
- SqlTransformerSupport transformerSupport, QGenericObjectMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public @NotNull MGenericObject toRowObjectWithoutFullObject(
- GenericObjectType genericObject, JdbcSession jdbcSession) {
- MGenericObject row = super.toRowObjectWithoutFullObject(genericObject, jdbcSession);
-
- row.genericObjectTypeId = processCacheableUri(genericObject.getObjectType());
-
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java
index fd69cf7246b..92fb26d92ae 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QFocusMapping.java
@@ -13,11 +13,13 @@
import com.querydsl.core.types.Path;
import org.jetbrains.annotations.NotNull;
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
+import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
/**
@@ -32,16 +34,19 @@ public class QFocusMapping, R extends M
public static final String DEFAULT_ALIAS_NAME = "f";
- public static final QFocusMapping, MFocus> INSTANCE =
- new QFocusMapping<>(QFocus.TABLE_NAME, DEFAULT_ALIAS_NAME,
- FocusType.class, QFocus.CLASS);
+ public static QFocusMapping, ?, ?> init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QFocusMapping<>(QFocus.TABLE_NAME, DEFAULT_ALIAS_NAME,
+ FocusType.class, QFocus.CLASS,
+ repositoryContext);
+ }
protected QFocusMapping(
@NotNull String tableName,
@NotNull String defaultAliasName,
@NotNull Class schemaType,
- @NotNull Class queryType) {
- super(tableName, defaultAliasName, schemaType, queryType);
+ @NotNull Class queryType,
+ @NotNull SqaleRepoContext repositoryContext) {
+ super(tableName, defaultAliasName, schemaType, queryType, repositoryContext);
addItemMapping(F_COST_CENTER, stringMapper(q -> q.costCenter));
addItemMapping(F_EMAIL_ADDRESS, stringMapper(q -> q.emailAddress));
@@ -84,20 +89,8 @@ protected QFocusMapping(
.addItemMapping(ActivationType.F_LOCKOUT_STATUS,
enumMapper(q -> q.lockoutStatus));
- addRefMapping(F_PERSONA_REF, personaReferenceMapping());
- addRefMapping(F_LINK_REF, projectionReferenceMapping());
- }
-
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping personaReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_PERSONA;
- }
-
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping projectionReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_PROJECTION;
+ addRefMapping(F_PERSONA_REF, QObjectReferenceMapping.initForPersona(repositoryContext));
+ addRefMapping(F_LINK_REF, QObjectReferenceMapping.initForProjection(repositoryContext));
}
@Override
@@ -113,15 +106,68 @@ protected Q newAliasInstance(String alias) {
return (Q) new QFocus<>(MFocus.class, alias);
}
- @Override
- public FocusSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new FocusSqlTransformer<>(transformerSupport, this);
- }
-
@Override
public R newRowObject() {
//noinspection unchecked
return (R) new MFocus();
}
+
+ @SuppressWarnings("DuplicatedCode") // activation code duplicated with assignment
+ @Override
+ public @NotNull R toRowObjectWithoutFullObject(S focus, JdbcSession jdbcSession) {
+ R row = super.toRowObjectWithoutFullObject(focus, jdbcSession);
+
+ row.costCenter = focus.getCostCenter();
+ row.emailAddress = focus.getEmailAddress();
+ row.photo = focus.getJpegPhoto();
+ row.locale = focus.getLocale();
+ setPolyString(focus.getLocality(), o -> row.localityOrig = o, n -> row.localityNorm = n);
+ row.preferredLanguage = focus.getPreferredLanguage();
+ row.telephoneNumber = focus.getTelephoneNumber();
+ row.timezone = focus.getTimezone();
+
+ // credential/password/metadata (sorry for nesting, but the gets may not be so cheap)
+ CredentialsType credentials = focus.getCredentials();
+ if (credentials != null) {
+ PasswordType password = credentials.getPassword();
+ if (password != null) {
+ MetadataType passwordMetadata = password.getMetadata();
+ if (passwordMetadata != null) {
+ row.passwordCreateTimestamp =
+ MiscUtil.asInstant(passwordMetadata.getCreateTimestamp());
+ row.passwordModifyTimestamp =
+ MiscUtil.asInstant(passwordMetadata.getModifyTimestamp());
+ }
+ }
+ }
+
+ // activation
+ ActivationType activation = focus.getActivation();
+ if (activation != null) {
+ row.administrativeStatus = activation.getAdministrativeStatus();
+ row.effectiveStatus = activation.getEffectiveStatus();
+ row.enableTimestamp = MiscUtil.asInstant(activation.getEnableTimestamp());
+ row.disableTimestamp = MiscUtil.asInstant(activation.getDisableTimestamp());
+ row.disableReason = activation.getDisableReason();
+ row.validityStatus = activation.getValidityStatus();
+ row.validFrom = MiscUtil.asInstant(activation.getValidFrom());
+ row.validTo = MiscUtil.asInstant(activation.getValidTo());
+ row.validityChangeTimestamp = MiscUtil.asInstant(activation.getValidityChangeTimestamp());
+ row.archiveTimestamp = MiscUtil.asInstant(activation.getArchiveTimestamp());
+ row.lockoutStatus = activation.getLockoutStatus();
+ }
+
+ return row;
+ }
+
+ @Override
+ public void storeRelatedEntities(
+ @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) {
+ super.storeRelatedEntities(row, schemaObject, jdbcSession);
+
+ storeRefs(row, schemaObject.getLinkRef(),
+ QObjectReferenceMapping.getForProjection(), jdbcSession);
+ storeRefs(row, schemaObject.getPersonaRef(),
+ QObjectReferenceMapping.getForPersona(), jdbcSession);
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java
index 4b60efbb6f2..cbebd42c2a8 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QGenericObjectMapping.java
@@ -6,7 +6,10 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel.focus;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType;
/**
@@ -17,11 +20,13 @@ public class QGenericObjectMapping
public static final String DEFAULT_ALIAS_NAME = "go";
- public static final QGenericObjectMapping INSTANCE = new QGenericObjectMapping();
+ public static QGenericObjectMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QGenericObjectMapping(repositoryContext);
+ }
- private QGenericObjectMapping() {
+ private QGenericObjectMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QGenericObject.TABLE_NAME, DEFAULT_ALIAS_NAME,
- GenericObjectType.class, QGenericObject.class);
+ GenericObjectType.class, QGenericObject.class, repositoryContext);
}
@Override
@@ -30,13 +35,17 @@ protected QGenericObject newAliasInstance(String alias) {
}
@Override
- public GenericObjectSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new GenericObjectSqlTransformer(transformerSupport, this);
+ public MGenericObject newRowObject() {
+ return new MGenericObject();
}
@Override
- public MGenericObject newRowObject() {
- return new MGenericObject();
+ public @NotNull MGenericObject toRowObjectWithoutFullObject(
+ GenericObjectType genericObject, JdbcSession jdbcSession) {
+ MGenericObject row = super.toRowObjectWithoutFullObject(genericObject, jdbcSession);
+
+ row.genericObjectTypeId = processCacheableUri(genericObject.getObjectType());
+
+ return row;
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java
index bb47b491e48..e8941623253 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/QUserMapping.java
@@ -8,7 +8,10 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.UserType.*;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
/**
@@ -19,11 +22,13 @@ public class QUserMapping
public static final String DEFAULT_ALIAS_NAME = "u";
- public static final QUserMapping INSTANCE = new QUserMapping();
+ public static QUserMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QUserMapping(repositoryContext);
+ }
- private QUserMapping() {
+ private QUserMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QUser.TABLE_NAME, DEFAULT_ALIAS_NAME,
- UserType.class, QUser.class);
+ UserType.class, QUser.class, repositoryContext);
addItemMapping(F_ADDITIONAL_NAME, polyStringMapper(
q -> q.additionalNameOrig, q -> q.additionalNameNorm));
@@ -50,13 +55,33 @@ protected QUser newAliasInstance(String alias) {
}
@Override
- public UserSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new UserSqlTransformer(transformerSupport, this);
+ public MUser newRowObject() {
+ return new MUser();
}
@Override
- public MUser newRowObject() {
- return new MUser();
+ public @NotNull MUser toRowObjectWithoutFullObject(
+ UserType user, JdbcSession jdbcSession) {
+ MUser row = super.toRowObjectWithoutFullObject(user, jdbcSession);
+
+ setPolyString(user.getAdditionalName(),
+ o -> row.additionalNameOrig = o, n -> row.additionalNameNorm = n);
+ row.employeeNumber = user.getEmployeeNumber();
+ setPolyString(user.getFamilyName(),
+ o -> row.familyNameOrig = o, n -> row.familyNameNorm = n);
+ setPolyString(user.getFullName(), o -> row.fullNameOrig = o, n -> row.fullNameNorm = n);
+ setPolyString(user.getGivenName(), o -> row.givenNameOrig = o, n -> row.givenNameNorm = n);
+ setPolyString(user.getHonorificPrefix(),
+ o -> row.honorificPrefixOrig = o, n -> row.honorificPrefixNorm = n);
+ setPolyString(user.getHonorificSuffix(),
+ o -> row.honorificSuffixOrig = o, n -> row.honorificSuffixNorm = n);
+ setPolyString(user.getNickName(), o -> row.nickNameOrig = o, n -> row.nickNameNorm = n);
+ setPolyString(user.getTitle(), o -> row.titleOrig = o, n -> row.titleNorm = n);
+
+ // TODO:
+ // user.getOrganizationalUnit() -> m_user_organizational_unit
+ // user.getOrganization() -> m_user_organization
+
+ return row;
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java
deleted file mode 100644
index a2316192798..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/focus/UserSqlTransformer.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.qmodel.focus;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
-
-public class UserSqlTransformer
- extends FocusSqlTransformer {
-
- public UserSqlTransformer(
- SqlTransformerSupport transformerSupport, QUserMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public @NotNull MUser toRowObjectWithoutFullObject(
- UserType user, JdbcSession jdbcSession) {
- MUser row = super.toRowObjectWithoutFullObject(user, jdbcSession);
-
- setPolyString(user.getAdditionalName(),
- o -> row.additionalNameOrig = o, n -> row.additionalNameNorm = n);
- row.employeeNumber = user.getEmployeeNumber();
- setPolyString(user.getFamilyName(),
- o -> row.familyNameOrig = o, n -> row.familyNameNorm = n);
- setPolyString(user.getFullName(), o -> row.fullNameOrig = o, n -> row.fullNameNorm = n);
- setPolyString(user.getGivenName(), o -> row.givenNameOrig = o, n -> row.givenNameNorm = n);
- setPolyString(user.getHonorificPrefix(),
- o -> row.honorificPrefixOrig = o, n -> row.honorificPrefixNorm = n);
- setPolyString(user.getHonorificSuffix(),
- o -> row.honorificSuffixOrig = o, n -> row.honorificSuffixNorm = n);
- setPolyString(user.getNickName(), o -> row.nickNameOrig = o, n -> row.nickNameNorm = n);
- setPolyString(user.getTitle(), o -> row.titleOrig = o, n -> row.titleNorm = n);
-
- // TODO:
- // user.getOrganizationalUnit() -> m_user_organizational_unit
- // user.getOrganization() -> m_user_organization
-
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java
deleted file mode 100644
index b01d7baddd9..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableRowSqlTransformer.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.qmodel.lookuptable;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ContainerSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType;
-
-public class LookupTableRowSqlTransformer
- extends ContainerSqlTransformer {
-
- public LookupTableRowSqlTransformer(
- SqlTransformerSupport transformerSupport, QLookupTableRowMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public MLookupTableRow insert(LookupTableRowType lookupTableRow,
- MLookupTable ownerRow, JdbcSession jdbcSession) {
-
- MLookupTableRow row = initRowObject(lookupTableRow, ownerRow);
- row.key = lookupTableRow.getKey();
- row.value = lookupTableRow.getValue();
- setPolyString(lookupTableRow.getLabel(), o -> row.labelOrig = o, n -> row.labelNorm = n);
- row.lastChangeTimestamp = MiscUtil.asInstant(lookupTableRow.getLastChangeTimestamp());
-
- insert(row, jdbcSession);
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java
deleted file mode 100644
index 21941971077..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/LookupTableSqlTransformer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.qmodel.lookuptable;
-
-import java.util.List;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType;
-
-public class LookupTableSqlTransformer
- extends ObjectSqlTransformer {
-
- public LookupTableSqlTransformer(
- SqlTransformerSupport transformerSupport, QLookupTableMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public void storeRelatedEntities(
- @NotNull MLookupTable lookupTable,
- @NotNull LookupTableType schemaObject,
- @NotNull JdbcSession jdbcSession) {
- super.storeRelatedEntities(lookupTable, schemaObject, jdbcSession);
-
- List rows = schemaObject.getRow();
- if (!rows.isEmpty()) {
- LookupTableRowSqlTransformer transformer =
- QLookupTableRowMapping.INSTANCE.createTransformer(transformerSupport);
- rows.forEach(row -> transformer.insert(row, lookupTable, jdbcSession));
- }
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java
index 405d6ef9877..a7723179d0f 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableMapping.java
@@ -8,8 +8,14 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType.F_ROW;
+import java.util.List;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType;
/**
@@ -20,13 +26,16 @@ public class QLookupTableMapping
public static final String DEFAULT_ALIAS_NAME = "lt";
- public static final QLookupTableMapping INSTANCE = new QLookupTableMapping();
+ public static QLookupTableMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QLookupTableMapping(repositoryContext);
+ }
- private QLookupTableMapping() {
+ private QLookupTableMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QLookupTable.TABLE_NAME, DEFAULT_ALIAS_NAME,
- LookupTableType.class, QLookupTable.class);
+ LookupTableType.class, QLookupTable.class, repositoryContext);
- addContainerTableMapping(F_ROW, QLookupTableRowMapping.INSTANCE,
+ addContainerTableMapping(F_ROW,
+ QLookupTableRowMapping.init(repositoryContext),
joinOn((o, t) -> o.oid.eq(t.ownerOid)));
}
@@ -36,12 +45,21 @@ protected QLookupTable newAliasInstance(String alias) {
}
@Override
- public LookupTableSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new LookupTableSqlTransformer(transformerSupport, this);
+ public MLookupTable newRowObject() {
+ return new MLookupTable();
}
@Override
- public MLookupTable newRowObject() {
- return new MLookupTable();
+ public void storeRelatedEntities(
+ @NotNull MLookupTable lookupTable,
+ @NotNull LookupTableType schemaObject,
+ @NotNull JdbcSession jdbcSession) {
+ super.storeRelatedEntities(lookupTable, schemaObject, jdbcSession);
+
+ List rows = schemaObject.getRow();
+ if (!rows.isEmpty()) {
+ rows.forEach(row ->
+ QLookupTableRowMapping.get().insert(row, lookupTable, jdbcSession));
+ }
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java
index faaf1e9ae64..e7a295f5a91 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/lookuptable/QLookupTableRowMapping.java
@@ -8,8 +8,14 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType.*;
+import java.util.Objects;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableRowType;
/**
@@ -20,11 +26,22 @@ public class QLookupTableRowMapping
public static final String DEFAULT_ALIAS_NAME = "ltr";
- public static final QLookupTableRowMapping INSTANCE = new QLookupTableRowMapping();
+ private static QLookupTableRowMapping instance;
+
+ public static QLookupTableRowMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ if (instance == null) {
+ instance = new QLookupTableRowMapping(repositoryContext);
+ }
+ return instance;
+ }
+
+ public static QLookupTableRowMapping get() {
+ return Objects.requireNonNull(instance);
+ }
- private QLookupTableRowMapping() {
+ private QLookupTableRowMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QLookupTableRow.TABLE_NAME, DEFAULT_ALIAS_NAME,
- LookupTableRowType.class, QLookupTableRow.class);
+ LookupTableRowType.class, QLookupTableRow.class, repositoryContext);
addItemMapping(F_KEY, stringMapper(q -> q.key));
addItemMapping(F_LABEL, polyStringMapper(
@@ -39,11 +56,6 @@ protected QLookupTableRow newAliasInstance(String alias) {
return new QLookupTableRow(alias);
}
- @Override
- public LookupTableRowSqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new LookupTableRowSqlTransformer(transformerSupport, this);
- }
-
@Override
public MLookupTableRow newRowObject() {
return new MLookupTableRow();
@@ -55,4 +67,18 @@ public MLookupTableRow newRowObject(MLookupTable ownerRow) {
row.ownerOid = ownerRow.oid;
return row;
}
+
+ @Override
+ public MLookupTableRow insert(LookupTableRowType lookupTableRow,
+ MLookupTable ownerRow, JdbcSession jdbcSession) {
+
+ MLookupTableRow row = initRowObject(lookupTableRow, ownerRow);
+ row.key = lookupTableRow.getKey();
+ row.value = lookupTableRow.getValue();
+ setPolyString(lookupTableRow.getLabel(), o -> row.labelOrig = o, n -> row.labelNorm = n);
+ row.lastChangeTimestamp = MiscUtil.asInstant(lookupTableRow.getLastChangeTimestamp());
+
+ insert(row, jdbcSession);
+ return row;
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java
deleted file mode 100644
index b6003939f26..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/NodeSqlTransformer.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.qmodel.node;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.repo.sqale.qmodel.object.ObjectSqlTransformer;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType;
-
-public class NodeSqlTransformer
- extends ObjectSqlTransformer {
-
- public NodeSqlTransformer(
- SqlTransformerSupport transformerSupport, QNodeMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public @NotNull MNode toRowObjectWithoutFullObject(NodeType node, JdbcSession jdbcSession) {
- MNode row = super.toRowObjectWithoutFullObject(node, jdbcSession);
-
- row.nodeIdentifier = node.getNodeIdentifier();
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java
index 38bf3917847..397cd366306 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/node/QNodeMapping.java
@@ -8,8 +8,11 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType.F_NODE_IDENTIFIER;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.object.QObjectMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType;
/**
@@ -20,10 +23,13 @@ public class QNodeMapping
public static final String DEFAULT_ALIAS_NAME = "nod";
- public static final QNodeMapping INSTANCE = new QNodeMapping();
+ public static QNodeMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QNodeMapping(repositoryContext);
+ }
- private QNodeMapping() {
- super(QNode.TABLE_NAME, DEFAULT_ALIAS_NAME, NodeType.class, QNode.class);
+ private QNodeMapping(@NotNull SqaleRepoContext repositoryContext) {
+ super(QNode.TABLE_NAME, DEFAULT_ALIAS_NAME,
+ NodeType.class, QNode.class, repositoryContext);
addItemMapping(F_NODE_IDENTIFIER, stringMapper(q -> q.nodeIdentifier));
}
@@ -34,13 +40,15 @@ protected QNode newAliasInstance(String alias) {
}
@Override
- public NodeSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new NodeSqlTransformer(transformerSupport, this);
+ public MNode newRowObject() {
+ return new MNode();
}
@Override
- public MNode newRowObject() {
- return new MNode();
+ public @NotNull MNode toRowObjectWithoutFullObject(NodeType node, JdbcSession jdbcSession) {
+ MNode row = super.toRowObjectWithoutFullObject(node, jdbcSession);
+
+ row.nodeIdentifier = node.getNodeIdentifier();
+ return row;
}
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java
deleted file mode 100644
index 4788cdb3bef..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ContainerSqlTransformer.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.qmodel.object;
-
-import com.evolveum.midpoint.prism.Containerable;
-import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTransformerBase;
-import com.evolveum.midpoint.repo.sqale.qmodel.TransformerForOwnedBy;
-import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainer;
-import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainer;
-import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-
-/**
- * @param schema type
- * @param type of entity path
- * @param type of the row bean for the table
- * @param type of the owner row (table owning the container)
- */
-public class ContainerSqlTransformer
- , R extends MContainer, OR>
- extends SqaleTransformerBase
- implements TransformerForOwnedBy {
-
- private final QContainerMapping mapping;
-
- public ContainerSqlTransformer(
- SqlTransformerSupport transformerSupport, QContainerMapping mapping) {
- super(transformerSupport);
- this.mapping = mapping;
- }
-
- @Override
- protected QContainerMapping mapping() {
- return mapping;
- }
-
- /**
- * This creates the right type of object and fills in the base {@link MContainer} attributes.
- */
- public R initRowObject(S schemaObject, OR ownerRow) {
- R row = mapping.newRowObject(ownerRow);
- row.cid = schemaObject.asPrismContainerValue().getId();
- // containerType is generated in DB, must be left null!
- return row;
- }
-
- @Override
- public R insert(S schemaObject, OR ownerRow, JdbcSession jdbcSession) {
- throw new UnsupportedOperationException("insert not implemented in the subclass");
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java
deleted file mode 100644
index f34779d1dce..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/ObjectSqlTransformer.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.qmodel.object;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import javax.xml.namespace.QName;
-
-import com.querydsl.core.Tuple;
-import org.jetbrains.annotations.NotNull;
-
-import com.evolveum.midpoint.prism.PrismObject;
-import com.evolveum.midpoint.prism.SerializationOptions;
-import com.evolveum.midpoint.repo.sqale.SqaleUtils;
-import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTransformerBase;
-import com.evolveum.midpoint.repo.sqale.qmodel.assignment.AssignmentSqlTransformer;
-import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri;
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.schema.GetOperationOptions;
-import com.evolveum.midpoint.schema.SelectorOptions;
-import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.util.exception.SchemaException;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
-
-public class ObjectSqlTransformer, R extends MObject>
- extends SqaleTransformerBase {
-
- private final QObjectMapping mapping;
-
- public ObjectSqlTransformer(
- SqlTransformerSupport transformerSupport,
- QObjectMapping mapping) {
- super(transformerSupport);
- this.mapping = mapping;
- }
-
- @Override
- protected QObjectMapping mapping() {
- return mapping;
- }
-
- @Override
- public S toSchemaObject(Tuple row, Q entityPath,
- Collection> options)
- throws SchemaException {
-
- byte[] fullObject = Objects.requireNonNull(row.get(entityPath.fullObject));
-
- PrismObject prismObject;
- String serializedForm = new String(fullObject, StandardCharsets.UTF_8);
- try {
- SqlTransformerSupport.ParseResult result =
- transformerSupport.parsePrismObject(serializedForm);
- prismObject = result.prismObject;
- if (result.parsingContext.hasWarnings()) {
- logger.warn("Object {} parsed with {} warnings",
- ObjectTypeUtil.toShortString(prismObject),
- result.parsingContext.getWarnings().size());
- }
- } catch (SchemaException | RuntimeException | Error e) {
- // This is a serious thing. We have corrupted XML in the repo. This may happen even
- // during system init. We want really loud and detailed error here.
- logger.error("Couldn't parse object {} {}: {}: {}\n{}",
- mapping.schemaType().getSimpleName(), row.get(entityPath.oid),
- e.getClass().getName(), e.getMessage(), serializedForm, e);
- throw e;
- }
-
- return prismObject.asObjectable();
- }
-
- /**
- * Override this to fill additional row attributes after calling this super version.
- *
- * *This must be called with active JDBC session* so it can create new {@link QUri} rows.
- * As this is intended for inserts *DO NOT* set {@link MObject#objectType} to any value,
- * it must be NULL otherwise the DB will complain about the value for the generated column.
- *
- * OID may be null, hence the method does NOT create any sub-entities, see
- * {@link #storeRelatedEntities(MObject, ObjectType, JdbcSession)}.
- * Try to keep order of fields here, in M-class (MObject for this one) and in SQL the same.
- */
- @SuppressWarnings("DuplicatedCode") // see comment for metadata lower
- @NotNull
- public R toRowObjectWithoutFullObject(S schemaObject, JdbcSession jdbcSession) {
- R row = mapping.newRowObject();
-
- row.oid = oidToUUid(schemaObject.getOid());
- // objectType MUST be left NULL for INSERT, it's determined by PG
- setPolyString(schemaObject.getName(), o -> row.nameOrig = o, n -> row.nameNorm = n);
- // fullObject is managed outside of this method
- setReference(schemaObject.getTenantRef(),
- o -> row.tenantRefTargetOid = o,
- t -> row.tenantRefTargetType = t,
- r -> row.tenantRefRelationId = r);
- row.lifecycleState = schemaObject.getLifecycleState();
- // containerIdSeq is managed outside of this method
- row.version = SqaleUtils.objectVersionAsInt(schemaObject);
-
- // complex DB fields
- row.policySituations = processCacheableUris(schemaObject.getPolicySituation());
- row.subtypes = arrayFor(schemaObject.getSubtype());
- // TODO textInfo (fulltext support)
- // repo.getTextInfoItems().addAll(RObjectTextInfo.createItemsSet(jaxb, repo, repositoryContext));
- // TODO extensions stored inline (JSON) - that is ext column
-
- // This is duplicate code with AssignmentSqlTransformer.toRowObject, but making interface
- // and needed setters (fields are not "interface-able") would create much more code.
- MetadataType metadata = schemaObject.getMetadata();
- if (metadata != null) {
- setReference(metadata.getCreatorRef(),
- o -> row.creatorRefTargetOid = o,
- t -> row.creatorRefTargetType = t,
- r -> row.creatorRefRelationId = r);
- row.createChannelId = processCacheableUri(metadata.getCreateChannel());
- row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp());
-
- setReference(metadata.getModifierRef(),
- o -> row.modifierRefTargetOid = o,
- t -> row.modifierRefTargetType = t,
- r -> row.modifierRefRelationId = r);
- row.modifyChannelId = processCacheableUri(metadata.getModifyChannel());
- row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp());
- }
- return row;
- }
-
- /**
- * Stores other entities related to the main object row like containers, references, etc.
- * This is not part of {@link #toRowObjectWithoutFullObject} because it requires know OID
- * which is not assured before calling that method.
- *
- * *Always call this super method first in overriding methods.*
- *
- * @param row master row for the added object("aggregate root")
- * @param schemaObject schema objects for which the details are stored
- * @param jdbcSession JDBC session used to insert related rows
- */
- public void storeRelatedEntities(
- @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) {
- Objects.requireNonNull(row.oid);
-
- // We're after insert, we can set this for the needs of owned entities (assignments).
- row.objectType = MObjectType.fromSchemaType(schemaObject.getClass());
-
- MetadataType metadata = schemaObject.getMetadata();
- if (metadata != null) {
- storeRefs(row, metadata.getCreateApproverRef(),
- mapping.objectCreateApproverReferenceMapping(), jdbcSession);
- storeRefs(row, metadata.getModifyApproverRef(),
- mapping.objectModifyApproverReferenceMapping(), jdbcSession);
- }
-
- List triggers = schemaObject.getTrigger();
- if (!triggers.isEmpty()) {
- TriggerSqlTransformer transformer =
- mapping.triggerMapping().createTransformer(transformerSupport);
- triggers.forEach(t -> transformer.insert(t, row, jdbcSession));
- }
-
- List operationExecutions = schemaObject.getOperationExecution();
- if (!operationExecutions.isEmpty()) {
- OperationExecutionSqlTransformer transformer =
- mapping.operationExecutionMapping().createTransformer(transformerSupport);
- operationExecutions.forEach(oe -> transformer.insert(oe, row, jdbcSession));
- }
-
- storeRefs(row, schemaObject.getParentOrgRef(),
- mapping.objectParentOrgReferenceMapping(), jdbcSession);
-
- if (schemaObject instanceof AssignmentHolderType) {
- storeAssignmentHolderEntities(row, (AssignmentHolderType) schemaObject, jdbcSession);
- }
-
- /* TODO EAV extensions - the relevant code from old repo RObject#copyObjectInformationFromJAXB
- if (jaxb.getExtension() != null) {
- copyExtensionOrAttributesFromJAXB(jaxb.getExtension().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.EXTENSION, generatorResult);
- }
- */
- }
-
- private void storeAssignmentHolderEntities(
- R row, AssignmentHolderType schemaObject, JdbcSession jdbcSession) {
- List assignments = schemaObject.getAssignment();
- if (!assignments.isEmpty()) {
- AssignmentSqlTransformer transformer =
- mapping.assignmentMapping().createTransformer(transformerSupport);
- assignments.forEach(assignment ->
- transformer.insert(assignment, row, jdbcSession));
- }
-
- storeRefs(row, schemaObject.getArchetypeRef(),
- mapping.archetypeReferenceMapping(), jdbcSession);
- storeRefs(row, schemaObject.getDelegatedRef(),
- mapping.delegatedReferenceMapping(), jdbcSession);
- storeRefs(row, schemaObject.getRoleMembershipRef(),
- mapping.roleMembershipReferenceMapping(), jdbcSession);
- }
-
- /**
- * 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 || schemaObject.getVersion() == null) {
- throw new IllegalArgumentException(
- "Serialized object must have assigned OID and version: " + schemaObject);
- }
-
- return transformerSupport.createStringSerializer()
- .itemsToSkip(fullObjectItemsToSkip())
- .options(SerializationOptions
- .createSerializeReferenceNamesForNullOids()
- .skipIndexOnly(true)
- .skipTransient(true))
- .serialize(schemaObject.asPrismObject())
- .getBytes(StandardCharsets.UTF_8);
- }
-
- protected Collection extends QName> 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/qmodel/object/OperationExecutionSqlTransformer.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/OperationExecutionSqlTransformer.java
deleted file mode 100644
index 3048955b408..00000000000
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/OperationExecutionSqlTransformer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.qmodel.object;
-
-import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.util.MiscUtil;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType;
-
-public class OperationExecutionSqlTransformer
- extends ContainerSqlTransformer, MOperationExecution, OR> {
-
- public OperationExecutionSqlTransformer(
- SqlTransformerSupport transformerSupport, QOperationExecutionMapping mapping) {
- super(transformerSupport, mapping);
- }
-
- @Override
- public MOperationExecution insert(
- OperationExecutionType schemaObject, OR ownerRow, JdbcSession jdbcSession) {
- MOperationExecution row = initRowObject(schemaObject, ownerRow);
-
- row.status = schemaObject.getStatus();
- row.recordType = schemaObject.getRecordType();
- setReference(schemaObject.getInitiatorRef(),
- o -> row.initiatorRefTargetOid = o,
- t -> row.initiatorRefTargetType = t,
- r -> row.initiatorRefRelationId = r);
- setReference(schemaObject.getTaskRef(),
- o -> row.taskRefTargetOid = o,
- t -> row.taskRefTargetType = t,
- r -> row.taskRefRelationId = r);
- row.timestampValue = MiscUtil.asInstant(schemaObject.getTimestamp());
-
- insert(row, jdbcSession);
- return row;
- }
-}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java
index b4afee53417..170ce467d08 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QAssignmentHolderMapping.java
@@ -6,6 +6,9 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel.object;
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType;
/**
@@ -21,11 +24,14 @@ public class QAssignmentHolderMapping extends QObjectMapping<
public static final String DEFAULT_ALIAS_NAME = "ah";
- public static final QAssignmentHolderMapping INSTANCE = new QAssignmentHolderMapping();
+ public static QAssignmentHolderMapping init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QAssignmentHolderMapping(repositoryContext);
+ }
- protected QAssignmentHolderMapping() {
+ protected QAssignmentHolderMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QObject.TABLE_NAME, DEFAULT_ALIAS_NAME,
- AssignmentHolderType.class, QAssignmentHolder.class);
+ AssignmentHolderType.class, QAssignmentHolder.class,
+ repositoryContext);
}
public static class MAssignmentHolder extends MObject {
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java
index f33c8922acb..1f547918431 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QObjectMapping.java
@@ -8,22 +8,34 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType.*;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import javax.xml.namespace.QName;
+import com.querydsl.core.Tuple;
import com.querydsl.core.types.Path;
import org.jetbrains.annotations.NotNull;
import com.evolveum.midpoint.prism.PrismConstants;
+import com.evolveum.midpoint.prism.PrismObject;
+import com.evolveum.midpoint.prism.SerializationOptions;
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
+import com.evolveum.midpoint.repo.sqale.SqaleUtils;
import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.assignment.QAssignmentMapping;
+import com.evolveum.midpoint.repo.sqale.qmodel.common.QUri;
import com.evolveum.midpoint.repo.sqale.qmodel.ref.QObjectReferenceMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
-import com.evolveum.midpoint.repo.sqlbase.mapping.SqlTransformer;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.repo.sqlbase.RepositoryObjectParseResult;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType;
-import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
+import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
+import com.evolveum.midpoint.util.MiscUtil;
+import com.evolveum.midpoint.util.exception.SchemaException;
+import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
/**
* Mapping between {@link QObject} and {@link ObjectType}.
@@ -37,16 +49,20 @@ public class QObjectMapping, R extend
public static final String DEFAULT_ALIAS_NAME = "o";
- public static final QObjectMapping, MObject> INSTANCE =
- new QObjectMapping<>(QObject.TABLE_NAME, DEFAULT_ALIAS_NAME,
- ObjectType.class, QObject.CLASS);
+ public static QObjectMapping, ?, ?> init(@NotNull SqaleRepoContext repositoryContext) {
+ return new QObjectMapping<>(
+ QObject.TABLE_NAME, DEFAULT_ALIAS_NAME,
+ ObjectType.class, QObject.CLASS,
+ repositoryContext);
+ }
protected QObjectMapping(
@NotNull String tableName,
@NotNull String defaultAliasName,
@NotNull Class schemaType,
- @NotNull Class queryType) {
- super(tableName, defaultAliasName, schemaType, queryType);
+ @NotNull Class queryType,
+ @NotNull SqaleRepoContext repositoryContext) {
+ super(tableName, defaultAliasName, schemaType, queryType, repositoryContext);
addItemMapping(PrismConstants.T_ID, uuidMapper(q -> q.oid));
addItemMapping(F_NAME, polyStringMapper(
@@ -79,104 +95,228 @@ protected QObjectMapping(
.addItemMapping(MetadataType.F_MODIFY_TIMESTAMP,
timestampMapper(q -> q.modifyTimestamp))
.addRefMapping(MetadataType.F_CREATE_APPROVER_REF,
- objectCreateApproverReferenceMapping())
+ QObjectReferenceMapping.initForObjectCreateApprover(repositoryContext))
.addRefMapping(MetadataType.F_MODIFY_APPROVER_REF,
- objectModifyApproverReferenceMapping());
+ QObjectReferenceMapping.initForObjectModifyApprover(repositoryContext));
- addRefMapping(F_PARENT_ORG_REF, objectParentOrgReferenceMapping());
+ addRefMapping(F_PARENT_ORG_REF,
+ QObjectReferenceMapping.initForObjectParentOrg(repositoryContext));
- addContainerTableMapping(AssignmentHolderType.F_ASSIGNMENT, assignmentMapping(),
+ addContainerTableMapping(AssignmentHolderType.F_ASSIGNMENT,
+ QAssignmentMapping.initAssignment(repositoryContext),
joinOn((o, a) -> o.oid.eq(a.ownerOid)));
- addContainerTableMapping(F_OPERATION_EXECUTION, operationExecutionMapping(),
+ addContainerTableMapping(F_OPERATION_EXECUTION,
+ QOperationExecutionMapping.init(repositoryContext),
joinOn((o, trg) -> o.oid.eq(trg.ownerOid)));
- addContainerTableMapping(F_TRIGGER, triggerMapping(),
+ addContainerTableMapping(F_TRIGGER,
+ QTriggerMapping.init(repositoryContext),
joinOn((o, trg) -> o.oid.eq(trg.ownerOid)));
// AssignmentHolderType
- addRefMapping(F_ARCHETYPE_REF, archetypeReferenceMapping());
- addRefMapping(F_DELEGATED_REF, delegatedReferenceMapping());
- addRefMapping(F_ROLE_MEMBERSHIP_REF, roleMembershipReferenceMapping());
+ addRefMapping(F_ARCHETYPE_REF, QObjectReferenceMapping.initForArchetype(repositoryContext));
+ addRefMapping(F_DELEGATED_REF, QObjectReferenceMapping.initForDelegated(repositoryContext));
+ addRefMapping(F_ROLE_MEMBERSHIP_REF,
+ QObjectReferenceMapping.initForRoleMembership(repositoryContext));
}
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- @NotNull
- public QAssignmentMapping assignmentMapping() {
- //noinspection unchecked
- return (QAssignmentMapping) QAssignmentMapping.INSTANCE;
+ @Override
+ public @NotNull Path>[] selectExpressions(
+ Q entity, Collection> options) {
+ return new Path[] { entity.oid, entity.fullObject };
}
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- @NotNull
- public QOperationExecutionMapping operationExecutionMapping() {
+ @Override
+ protected Q newAliasInstance(String alias) {
//noinspection unchecked
- return (QOperationExecutionMapping) QOperationExecutionMapping.INSTANCE;
+ return (Q) new QObject<>(MObject.class, alias);
}
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- @NotNull
- public QTriggerMapping triggerMapping() {
+ @Override
+ public R newRowObject() {
//noinspection unchecked
- return (QTriggerMapping) QTriggerMapping.INSTANCE;
+ return (R) new MObject();
}
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping archetypeReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_ARCHETYPE;
- }
+ // region transformation
+ @Override
+ public S toSchemaObject(Tuple row, Q entityPath,
+ Collection> options)
+ throws SchemaException {
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping delegatedReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_DELEGATED;
- }
+ byte[] fullObject = Objects.requireNonNull(row.get(entityPath.fullObject));
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping objectCreateApproverReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping)
- QObjectReferenceMapping.INSTANCE_OBJECT_CREATE_APPROVER;
- }
+ PrismObject prismObject;
+ String serializedForm = new String(fullObject, StandardCharsets.UTF_8);
+ try {
+ RepositoryObjectParseResult result =
+ repositoryContext().parsePrismObject(serializedForm);
+ prismObject = result.prismObject;
+ if (result.parsingContext.hasWarnings()) {
+ logger.warn("Object {} parsed with {} warnings",
+ ObjectTypeUtil.toShortString(prismObject),
+ result.parsingContext.getWarnings().size());
+ }
+ } catch (SchemaException | RuntimeException | Error e) {
+ // This is a serious thing. We have corrupted XML in the repo. This may happen even
+ // during system init. We want really loud and detailed error here.
+ logger.error("Couldn't parse object {} {}: {}: {}\n{}",
+ schemaType().getSimpleName(), row.get(entityPath.oid),
+ e.getClass().getName(), e.getMessage(), serializedForm, e);
+ throw e;
+ }
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping objectModifyApproverReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping)
- QObjectReferenceMapping.INSTANCE_OBJECT_MODIFY_APPROVER;
+ return prismObject.asObjectable();
}
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping objectParentOrgReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_OBJECT_PARENT_ORG;
+ /**
+ * Override this to fill additional row attributes after calling this super version.
+ *
+ * *This must be called with active JDBC session* so it can create new {@link QUri} rows.
+ * As this is intended for inserts *DO NOT* set {@link MObject#objectType} to any value,
+ * it must be NULL otherwise the DB will complain about the value for the generated column.
+ *
+ * OID may be null, hence the method does NOT create any sub-entities, see
+ * {@link #storeRelatedEntities(MObject, ObjectType, JdbcSession)}.
+ * Try to keep order of fields here, in M-class (MObject for this one) and in SQL the same.
+ */
+ @SuppressWarnings("DuplicatedCode") // see comment for metadata lower
+ @NotNull
+ public R toRowObjectWithoutFullObject(S schemaObject, JdbcSession jdbcSession) {
+ R row = newRowObject();
+
+ row.oid = oidToUUid(schemaObject.getOid());
+ // objectType MUST be left NULL for INSERT, it's determined by PG
+ setPolyString(schemaObject.getName(), o -> row.nameOrig = o, n -> row.nameNorm = n);
+ // fullObject is managed outside of this method
+ setReference(schemaObject.getTenantRef(),
+ o -> row.tenantRefTargetOid = o,
+ t -> row.tenantRefTargetType = t,
+ r -> row.tenantRefRelationId = r);
+ row.lifecycleState = schemaObject.getLifecycleState();
+ // containerIdSeq is managed outside of this method
+ row.version = SqaleUtils.objectVersionAsInt(schemaObject);
+
+ // complex DB fields
+ row.policySituations = processCacheableUris(schemaObject.getPolicySituation());
+ row.subtypes = arrayFor(schemaObject.getSubtype());
+ // TODO textInfo (fulltext support)
+ // repo.getTextInfoItems().addAll(RObjectTextInfo.createItemsSet(jaxb, repo, repositoryContext));
+ // TODO extensions stored inline (JSON) - that is ext column
+
+ // This is duplicate code with QAssignmentMapping.insert, but making interface
+ // and needed setters (fields are not "interface-able") would create much more code.
+ MetadataType metadata = schemaObject.getMetadata();
+ if (metadata != null) {
+ setReference(metadata.getCreatorRef(),
+ o -> row.creatorRefTargetOid = o,
+ t -> row.creatorRefTargetType = t,
+ r -> row.creatorRefRelationId = r);
+ row.createChannelId = processCacheableUri(metadata.getCreateChannel());
+ row.createTimestamp = MiscUtil.asInstant(metadata.getCreateTimestamp());
+
+ setReference(metadata.getModifierRef(),
+ o -> row.modifierRefTargetOid = o,
+ t -> row.modifierRefTargetType = t,
+ r -> row.modifierRefRelationId = r);
+ row.modifyChannelId = processCacheableUri(metadata.getModifyChannel());
+ row.modifyTimestamp = MiscUtil.asInstant(metadata.getModifyTimestamp());
+ }
+ return row;
}
- /** Fixes rigid parametric types of static mapping instance to this instance. */
- public @NotNull QObjectReferenceMapping roleMembershipReferenceMapping() {
- //noinspection unchecked
- return (QObjectReferenceMapping) QObjectReferenceMapping.INSTANCE_ROLE_MEMBERSHIP;
+ /**
+ * Stores other entities related to the main object row like containers, references, etc.
+ * This is not part of {@link #toRowObjectWithoutFullObject} because it requires know OID
+ * which is not assured before calling that method.
+ *
+ * *Always call this super method first in overriding methods.*
+ *
+ * @param row master row for the added object("aggregate root")
+ * @param schemaObject schema objects for which the details are stored
+ * @param jdbcSession JDBC session used to insert related rows
+ */
+ public void storeRelatedEntities(
+ @NotNull R row, @NotNull S schemaObject, @NotNull JdbcSession jdbcSession) {
+ Objects.requireNonNull(row.oid);
+
+ // We're after insert, we can set this for the needs of owned entities (assignments).
+ row.objectType = MObjectType.fromSchemaType(schemaObject.getClass());
+
+ MetadataType metadata = schemaObject.getMetadata();
+ if (metadata != null) {
+ storeRefs(row, metadata.getCreateApproverRef(),
+ QObjectReferenceMapping.getForObjectCreateApprover(), jdbcSession);
+ storeRefs(row, metadata.getModifyApproverRef(),
+ QObjectReferenceMapping.getForObjectModifyApprover(), jdbcSession);
+ }
+
+ List triggers = schemaObject.getTrigger();
+ if (!triggers.isEmpty()) {
+ triggers.forEach(t -> QTriggerMapping.get().insert(t, row, jdbcSession));
+ }
+
+ List operationExecutions = schemaObject.getOperationExecution();
+ if (!operationExecutions.isEmpty()) {
+ operationExecutions.forEach(oe ->
+ QOperationExecutionMapping.get().insert(oe, row, jdbcSession));
+ }
+
+ storeRefs(row, schemaObject.getParentOrgRef(),
+ QObjectReferenceMapping.getForObjectParentOrg(), jdbcSession);
+
+ if (schemaObject instanceof AssignmentHolderType) {
+ storeAssignmentHolderEntities(row, (AssignmentHolderType) schemaObject, jdbcSession);
+ }
+
+ /* TODO EAV extensions - the relevant code from old repo RObject#copyObjectInformationFromJAXB
+ if (jaxb.getExtension() != null) {
+ copyExtensionOrAttributesFromJAXB(jaxb.getExtension().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.EXTENSION, generatorResult);
+ }
+ */
}
- @Override
- public @NotNull Path>[] selectExpressions(
- Q entity, Collection> options) {
- return new Path[] { entity.oid, entity.fullObject };
+ private void storeAssignmentHolderEntities(
+ R row, AssignmentHolderType schemaObject, JdbcSession jdbcSession) {
+ List assignments = schemaObject.getAssignment();
+ if (!assignments.isEmpty()) {
+ assignments.forEach(assignment ->
+ QAssignmentMapping.getAssignment().insert(assignment, row, jdbcSession));
+ }
+
+ storeRefs(row, schemaObject.getArchetypeRef(),
+ QObjectReferenceMapping.getForArchetype(), jdbcSession);
+ storeRefs(row, schemaObject.getDelegatedRef(),
+ QObjectReferenceMapping.getForDelegated(), jdbcSession);
+ storeRefs(row, schemaObject.getRoleMembershipRef(),
+ QObjectReferenceMapping.getForRoleMembership(), jdbcSession);
}
- @Override
- protected Q newAliasInstance(String alias) {
- //noinspection unchecked
- return (Q) new QObject<>(MObject.class, alias);
+ /**
+ * Serializes schema object and sets {@link R#fullObject}.
+ */
+ public void setFullObject(R row, S schemaObject) throws SchemaException {
+ row.fullObject = createFullObject(schemaObject);
}
- @Override
- public SqlTransformer createTransformer(SqlTransformerSupport transformerSupport) {
- return new ObjectSqlTransformer<>(transformerSupport, this);
+ public byte[] createFullObject(S schemaObject) throws SchemaException {
+ if (schemaObject.getOid() == null || schemaObject.getVersion() == null) {
+ throw new IllegalArgumentException(
+ "Serialized object must have assigned OID and version: " + schemaObject);
+ }
+
+ return repositoryContext().createStringSerializer()
+ .itemsToSkip(fullObjectItemsToSkip())
+ .options(SerializationOptions
+ .createSerializeReferenceNamesForNullOids()
+ .skipIndexOnly(true)
+ .skipTransient(true))
+ .serialize(schemaObject.asPrismObject())
+ .getBytes(StandardCharsets.UTF_8);
}
- @Override
- public R newRowObject() {
- //noinspection unchecked
- return (R) new MObject();
+ protected Collection extends QName> fullObjectItemsToSkip() {
+ // TODO extend later, things like FocusType.F_JPEG_PHOTO, see ObjectUpdater#updateFullObject
+ return Collections.emptyList();
}
+ // endregion
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java
index 427bed89379..8e1fd6c039a 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QOperationExecutionMapping.java
@@ -8,8 +8,14 @@
import static com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType.*;
+import java.util.Objects;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationExecutionType;
/**
@@ -22,14 +28,26 @@ public class QOperationExecutionMapping
public static final String DEFAULT_ALIAS_NAME = "opex";
- public static final QOperationExecutionMapping INSTANCE =
- new QOperationExecutionMapping<>();
+ private static QOperationExecutionMapping> instance;
+
+ public static QOperationExecutionMapping init(
+ @NotNull SqaleRepoContext repositoryContext) {
+ if (instance == null) {
+ instance = new QOperationExecutionMapping<>(repositoryContext);
+ }
+ return get();
+ }
+
+ public static QOperationExecutionMapping get() {
+ //noinspection unchecked
+ return (QOperationExecutionMapping) Objects.requireNonNull(instance);
+ }
// We can't declare Class>.class, so we cheat a bit.
@SuppressWarnings({ "unchecked", "rawtypes" })
- private QOperationExecutionMapping() {
+ private QOperationExecutionMapping(@NotNull SqaleRepoContext repositoryContext) {
super(QOperationExecution.TABLE_NAME, DEFAULT_ALIAS_NAME,
- OperationExecutionType.class, (Class) QOperationExecution.class);
+ OperationExecutionType.class, (Class) QOperationExecution.class, repositoryContext);
addItemMapping(F_STATUS, enumMapper(q -> q.status));
addItemMapping(F_RECORD_TYPE, enumMapper(q -> q.recordType));
@@ -50,12 +68,6 @@ protected QOperationExecution newAliasInstance(String alias) {
return new QOperationExecution<>(alias);
}
- @Override
- public OperationExecutionSqlTransformer createTransformer(
- SqlTransformerSupport transformerSupport) {
- return new OperationExecutionSqlTransformer<>(transformerSupport, this);
- }
-
@Override
public MOperationExecution newRowObject() {
return new MOperationExecution();
@@ -67,4 +79,25 @@ public MOperationExecution newRowObject(OR ownerRow) {
row.ownerOid = ownerRow.oid;
return row;
}
+
+ @Override
+ public MOperationExecution insert(
+ OperationExecutionType schemaObject, OR ownerRow, JdbcSession jdbcSession) {
+ MOperationExecution row = initRowObject(schemaObject, ownerRow);
+
+ row.status = schemaObject.getStatus();
+ row.recordType = schemaObject.getRecordType();
+ setReference(schemaObject.getInitiatorRef(),
+ o -> row.initiatorRefTargetOid = o,
+ t -> row.initiatorRefTargetType = t,
+ r -> row.initiatorRefRelationId = r);
+ setReference(schemaObject.getTaskRef(),
+ o -> row.taskRefTargetOid = o,
+ t -> row.taskRefTargetType = t,
+ r -> row.taskRefRelationId = r);
+ row.timestampValue = MiscUtil.asInstant(schemaObject.getTimestamp());
+
+ insert(row, jdbcSession);
+ return row;
+ }
}
diff --git a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java
index dd1019ddf14..49e0495fb21 100644
--- a/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java
+++ b/repo/repo-sqale/src/main/java/com/evolveum/midpoint/repo/sqale/qmodel/object/QTriggerMapping.java
@@ -6,8 +6,14 @@
*/
package com.evolveum.midpoint.repo.sqale.qmodel.object;
+import java.util.Objects;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.evolveum.midpoint.repo.sqale.SqaleRepoContext;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainerMapping;
-import com.evolveum.midpoint.repo.sqlbase.SqlTransformerSupport;
+import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
+import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType;
/**
@@ -20,13 +26,26 @@ public class QTriggerMapping
public static final String DEFAULT_ALIAS_NAME = "trg";
- public static final QTriggerMapping INSTANCE = new QTriggerMapping<>();
+ private static QTriggerMapping> instance;
+
+ public static