Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jun 30, 2021
2 parents bb2d274 + c434c43 commit 80d3d5c
Show file tree
Hide file tree
Showing 28 changed files with 785 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ public CompiledGuiProfile compileUserProfile(@NotNull List<AdminGuiConfiguration

CompiledGuiProfile composite = new CompiledGuiProfile();
if (globalAdminGuiConfig != null) {
applyAdminGuiConfiguration(composite, globalAdminGuiConfig, task, result);
applyAdminGuiConfiguration(composite, globalAdminGuiConfig.cloneWithoutId(), task, result);
}
for (AdminGuiConfigurationType adminGuiConfiguration: adminGuiConfigurations) {
applyAdminGuiConfiguration(composite, adminGuiConfiguration, task, result);
applyAdminGuiConfiguration(composite, adminGuiConfiguration.cloneWithoutId(), task, result);
}
return composite;
}
Expand Down
4 changes: 4 additions & 0 deletions model/model-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.0</version>
<version>2.5.2</version>
<!-- This parent also declares dependencies listed here:
https://docs.spring.io/spring-boot/docs/2.5.0/reference/html/dependency-versions.html#dependency-versions
https://docs.spring.io/spring-boot/docs/2.5.2/reference/html/dependency-versions.html#dependency-versions
Or for current version of Spring Boot:
https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-dependency-versions.html
-->
Expand Down
64 changes: 42 additions & 22 deletions repo/repo-sqale/sql/pgnew-repo.sql
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ CREATE TYPE ReferenceType AS ENUM (
'ARCHETYPE',
'ASSIGNMENT_CREATE_APPROVER',
'ASSIGNMENT_MODIFY_APPROVER',
'ACCESS_CERT_WI_ASSIGNEE',
'ACCESS_CERT_WI_CANDIDATE',
'CASE_WI_ASSIGNEE',
'CASE_WI_CANDIDATE',
'DELEGATED',
Expand Down Expand Up @@ -1306,7 +1308,6 @@ CREATE INDEX m_access_cert_campaign_policySituation_idx
ON m_access_cert_campaign USING GIN(policysituations gin__int_ops);
CREATE INDEX m_access_cert_campaign_ext_idx ON m_access_cert_campaign USING gin (ext);

-- TODO WIP
CREATE TABLE m_access_cert_case (
ownerOid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
containerType ContainerType GENERATED ALWAYS AS ('ACCESS_CERTIFICATION_CASE') STORED
Expand Down Expand Up @@ -1346,48 +1347,67 @@ CREATE TABLE m_access_cert_case (
)
INHERITS(m_container);

-- TODO not mapped yet
CREATE TABLE m_access_cert_wi (
ownerOid UUID NOT NULL, -- PK+FK
accCertCaseCid INTEGER NOT NULL, -- PK+FK
accessCertCaseCid INTEGER NOT NULL, -- PK+FK
containerType ContainerType GENERATED ALWAYS AS ('ACCESS_CERTIFICATION_WORK_ITEM') STORED
CHECK (containerType = 'ACCESS_CERTIFICATION_WORK_ITEM'),
closeTimestamp TIMESTAMPTZ,
campaignIteration INTEGER NOT NULL,
outcome TEXT,
outcome TEXT, -- stores output/outcome
outputChangeTimestamp TIMESTAMPTZ,
performerRefTargetOid UUID,
performerRefTargetType ObjectType,
performerRefRelationId INTEGER REFERENCES m_uri(id),
stageNumber INTEGER,

PRIMARY KEY (ownerOid, accCertCaseCid, cid)
PRIMARY KEY (ownerOid, accessCertCaseCid, cid)
)
INHERITS(m_container);

ALTER TABLE m_access_cert_wi
ADD CONSTRAINT m_access_cert_wi_id_fk FOREIGN KEY (ownerOid, accCertCaseCid)
ADD CONSTRAINT m_access_cert_wi_id_fk FOREIGN KEY (ownerOid, accessCertCaseCid)
REFERENCES m_access_cert_case (ownerOid, cid)
ON DELETE CASCADE;

-- TODO rework to inherit from reference tables
CREATE TABLE m_access_cert_wi_reference (
ownerOid UUID NOT NULL, -- PK+FK
accCertCaseCid INTEGER NOT NULL, -- PK+FK
accCertWiCid INTEGER NOT NULL, -- PK+FK
targetOid UUID NOT NULL, -- more PK columns...
targetType ObjectType,
relationId INTEGER NOT NULL REFERENCES m_uri(id),
-- stores case/workItem/assigneeRef
CREATE TABLE m_access_cert_wi_assignee (
ownerOid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
accessCertCaseCid INTEGER NOT NULL,
accessCertWorkItemCid INTEGER NOT NULL,
referenceType ReferenceType GENERATED ALWAYS AS ('ACCESS_CERT_WI_ASSIGNEE') STORED,

-- TODO is the order of last two components optimal for index/query?
PRIMARY KEY (ownerOid, accCertCaseCid, accCertWiCid, relationId, targetOid)
);
PRIMARY KEY (ownerOid, accessCertCaseCid, accessCertWorkItemCid, referenceType, relationId, targetOid)
)
INHERITS (m_reference);

ALTER TABLE m_access_cert_wi_assignee ADD CONSTRAINT m_access_cert_wi_assignee_id_fk_case
FOREIGN KEY (ownerOid, accessCertCaseCid) REFERENCES m_access_cert_case (ownerOid, cid);

ALTER TABLE m_access_cert_wi_assignee ADD CONSTRAINT m_access_cert_wi_assignee_id_fk_wi
FOREIGN KEY (ownerOid, accessCertCaseCid, accessCertWorkItemCid)
REFERENCES m_access_cert_wi (ownerOid, accessCertCaseCid, cid)
ON DELETE CASCADE; -- TODO is the cascade needed?

-- stores case/workItem/candidateRef
CREATE TABLE m_access_cert_wi_candidate (
ownerOid UUID NOT NULL REFERENCES m_object_oid(oid) ON DELETE CASCADE,
accessCertCaseCid INTEGER NOT NULL,
accessCertWorkItemCid INTEGER NOT NULL,
referenceType ReferenceType GENERATED ALWAYS AS ('ACCESS_CERT_WI_CANDIDATE') STORED,

PRIMARY KEY (ownerOid, accessCertCaseCid, accessCertWorkItemCid, referenceType, relationId, targetOid)
)
INHERITS (m_reference);

ALTER TABLE m_access_cert_wi_candidate ADD CONSTRAINT m_access_cert_wi_candidate_id_fk_case
FOREIGN KEY (ownerOid, accessCertCaseCid) REFERENCES m_access_cert_case (ownerOid, cid);

ALTER TABLE m_access_cert_wi_candidate ADD CONSTRAINT m_access_cert_wi_candidate_id_fk_wi
FOREIGN KEY (ownerOid, accessCertCaseCid, accessCertWorkItemCid)
REFERENCES m_access_cert_wi (ownerOid, accessCertCaseCid, cid)
ON DELETE CASCADE; -- TODO is the cascade needed?

ALTER TABLE m_access_cert_wi_reference
ADD CONSTRAINT m_access_cert_wi_reference_id_fk
FOREIGN KEY (ownerOid, accCertCaseCid, accCertWiCid)
REFERENCES m_access_cert_wi (ownerOid, accCertCaseCid, cid)
ON DELETE CASCADE;
/*
CREATE INDEX iCertCampaignNameOrig ON m_access_cert_campaign (nameOrig);
ALTER TABLE m_access_cert_campaign ADD CONSTRAINT uc_access_cert_campaign_name UNIQUE (nameNorm);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@

import javax.xml.namespace.QName;

import com.querydsl.core.types.Predicate;
import com.querydsl.sql.SQLQuery;
import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.query.InOidFilter;
import com.evolveum.midpoint.prism.query.OrgFilter;
import com.evolveum.midpoint.prism.query.*;
import com.evolveum.midpoint.repo.sqale.filtering.InOidFilterProcessor;
import com.evolveum.midpoint.repo.sqale.filtering.OrgFilterProcessor;
import com.evolveum.midpoint.repo.sqale.filtering.TypeFilterProcessor;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.QueryException;
import com.evolveum.midpoint.repo.sqlbase.RepositoryException;
import com.evolveum.midpoint.repo.sqlbase.SqlQueryContext;
import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.mapping.QueryTableMapping;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;

Expand Down Expand Up @@ -53,23 +55,34 @@ private SqaleQueryContext(
private SqaleQueryContext(
Q entityPath,
SqaleTableMapping<S, Q, R> mapping,
SqaleQueryContext<?, ?, ?> parentContext) {
super(entityPath, mapping, parentContext);
SqaleQueryContext<?, ?, ?> parentContext,
SQLQuery<?> sqlQuery) {
super(entityPath, mapping, parentContext, sqlQuery);
}

@Override
public SqaleRepoContext repositoryContext() {
return (SqaleRepoContext) super.repositoryContext();
}

@Override
public FilterProcessor<InOidFilter> createInOidFilter() {
return new InOidFilterProcessor(this);
public Predicate process(@NotNull ObjectFilter filter) throws RepositoryException {
// To compare with old repo see: QueryInterpreter.findAndCreateRestrictionInternal
if (filter instanceof InOidFilter) {
return new InOidFilterProcessor(this).process((InOidFilter) filter);
} else if (filter instanceof OrgFilter) {
return new OrgFilterProcessor(this).process((OrgFilter) filter);
} else if (filter instanceof FullTextFilter) {
// TODO
throw new QueryException("TODO filter " + filter);
} else if (filter instanceof ExistsFilter) {
// TODO
throw new QueryException("TODO filter " + filter);
} else if (filter instanceof TypeFilter) {
return new TypeFilterProcessor<>(this).process((TypeFilter) filter);
} else {
return super.process(filter);
}
}

@Override
public FilterProcessor<OrgFilter> createOrgFilter() {
return new OrgFilterProcessor(this);
public SqaleRepoContext repositoryContext() {
return (SqaleRepoContext) super.repositoryContext();
}

public @NotNull Integer searchCachedRelationId(QName qName) {
Expand All @@ -84,16 +97,26 @@ public void markContainsOrgFilter() {
}
}

/**
* Returns derived {@link SqaleQueryContext} for join or subquery.
*/
/** Returns derived {@link SqaleQueryContext} for JOIN. */
@Override
protected <TS, TQ extends FlexibleRelationalPathBase<TR>, TR> SqlQueryContext<TS, TQ, TR>
newSubcontext(TQ newPath, QueryTableMapping<TS, TQ, TR> newMapping) {
return new SqaleQueryContext<>(
newPath,
(SqaleTableMapping<TS, TQ, TR>) newMapping,
this,
this.sqlQuery);
}

/** Returns derived {@link SqaleQueryContext} for subquery. */
@Override
protected <TS, TQ extends FlexibleRelationalPathBase<TR>, TR> SqlQueryContext<TS, TQ, TR>
deriveNew(TQ newPath, QueryTableMapping<TS, TQ, TR> newMapping) {
newSubcontext(TQ newPath, QueryTableMapping<TS, TQ, TR> newMapping, SQLQuery<?> query) {
return new SqaleQueryContext<>(
newPath,
(SqaleTableMapping<TS, TQ, TR>) newMapping,
this);
this,
query);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import javax.xml.namespace.QName;

import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.sql.SQLQuery;

import com.evolveum.midpoint.prism.query.OrgFilter;
Expand All @@ -23,6 +22,7 @@
import com.evolveum.midpoint.repo.sqlbase.QueryException;
import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslUtils;

/**
* Filter processor that resolves {@link OrgFilter}.
Expand All @@ -42,7 +42,7 @@ public Predicate process(OrgFilter filter) throws QueryException {
FlexibleRelationalPathBase<?> path = context.root();
if (!(path instanceof QObject)) {
throw new QueryException("Org filter can only be used for objects,"
+ " not for path " + path + " of type " + path.getColumns());
+ " not for path " + path + " of type " + path.getClass());
}

QObject<?> objectPath = (QObject<?>) path;
Expand Down Expand Up @@ -101,7 +101,7 @@ public Predicate process(OrgFilter filter) throws QueryException {
}

private SQLQuery<Integer> subQuery(FlexibleRelationalPathBase<?> entityPath) {
return new SQLQuery<>().select(Expressions.constant(1))
return new SQLQuery<>().select(QuerydslUtils.EXPRESSION_ONE)
.from(entityPath);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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.filtering;

import com.querydsl.core.types.Predicate;

import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.TypeFilter;
import com.evolveum.midpoint.repo.sqale.SqaleQueryContext;
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.QObject;
import com.evolveum.midpoint.repo.sqlbase.QueryException;
import com.evolveum.midpoint.repo.sqlbase.RepositoryException;
import com.evolveum.midpoint.repo.sqlbase.filtering.FilterProcessor;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
import com.evolveum.midpoint.repo.sqlbase.querydsl.QuerydslUtils;

/**
* Filter processor that resolves {@link TypeFilter}.
*
* @param <Q> query type of the original context
* @param <R> row type related to {@link Q}
* @param <TQ> target query type for the type filter
* @param <TR> row type related to {@link TQ}
*/
public class TypeFilterProcessor<Q extends QObject<R>, R extends MObject, TQ extends QObject<TR>, TR extends MObject>
implements FilterProcessor<TypeFilter> {

private final SqaleQueryContext<?, Q, R> context;

public TypeFilterProcessor(SqaleQueryContext<?, ?, ?> context) throws QueryException {
FlexibleRelationalPathBase<?> path = context.root();
if (!(path instanceof QObject)) {
throw new QueryException("Type filter can only be used for objects,"
+ " not for path " + path + " of type " + path.getClass());
}

//noinspection unchecked
this.context = (SqaleQueryContext<?, Q, R>) context;
}

@Override
public Predicate process(TypeFilter filter) throws RepositoryException {
Q path = context.path();
//noinspection unchecked
Class<TQ> filterQueryType = (Class<TQ>)
MObjectType.fromTypeQName(filter.getType()).getQueryType();

ObjectFilter innerFilter = filter.getFilter();

if (path.getClass().equals(filterQueryType)) {
// Unexpected, but let's take the shortcut.
return innerFilter != null
? context.process(innerFilter)
: QuerydslUtils.EXPRESSION_TRUE;
// We can't just return null, we need some condition meaning "everything" for cases
// when the filter is in OR. It can't be just no-op in such cases.
} else {
SqaleQueryContext<?, TQ, TR> filterContext =
(SqaleQueryContext<?, TQ, TR>) context.subquery(filterQueryType);
filterContext.sqlQuery().where(filterContext.path().oid.eq(path.oid));

// Here we call processFilter that actually adds the WHERE conditions to the subquery.
filterContext.processFilter(innerFilter);
return filterContext.sqlQuery().exists(); // and this fulfills the processor contract
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
public class MAccessCertificationWorkItem extends MContainer {

public Long accCertCaseCid;
public Long accessCertCaseCid;

public Instant closeTimestamp;
public Integer campaignIteration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 com.evolveum.midpoint.repo.sqale.qmodel.ref.MReference;

/**
* Querydsl "row bean" type related to {@link QAccessCertificationWorkItemReference}.
*/
public class MAccessCertificationWorkItemReference extends MReference {

public Long accessCertCaseCid;
public Long accessCertWorkItemCid;

@Override
public String toString() {
return "MCaseWorkItemReference{" +
"ownerOid=" + ownerOid +
", accessCertCaseCid=" + accessCertCaseCid +
", accessCertWorkItemCid=" + accessCertWorkItemCid +
", referenceType=" + referenceType +
", targetOid=" + targetOid +
", targetType=" + targetType +
", relationId=" + relationId +
'}';
}
}

0 comments on commit 80d3d5c

Please sign in to comment.