Skip to content

Commit

Permalink
repo-sqale: ContainerTableUpdateContext used, first test runs
Browse files Browse the repository at this point in the history
There are still some gaping holes, it does not distinguish between
containers yet (missing where condition) and doesn't reuse paths.
This will be fixed when further tests are added.
  • Loading branch information
virgo47 committed Apr 27, 2021
1 parent 1cf0a03 commit c17a0c7
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 93 deletions.
Expand Up @@ -11,6 +11,7 @@
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.path.ItemName;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.repo.sqale.mapping.ContainerTableRelationResolver;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleItemRelationResolver;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleItemSqlMapper;
import com.evolveum.midpoint.repo.sqale.update.SqaleUpdateContext;
Expand Down Expand Up @@ -80,9 +81,21 @@ private QName resolvePath(ItemPath path) {
+ " in mapping " + mapping + " does not support delta modifications!");
}

ItemPath subcontextPath = firstName;
if (relationResolver instanceof ContainerTableRelationResolver) {
Object cid = path.first();
path = path.rest();
subcontextPath = ItemPath.create(firstName, cid);
}
// TODO check for existing subcontext

// we know nothing about context and resolver types, so we have to ignore it
//noinspection unchecked,rawtypes
context = ((SqaleItemRelationResolver) relationResolver).resolve(context);
SqaleUpdateContext subcontext =
((SqaleItemRelationResolver) relationResolver)
.resolve(this.context, subcontextPath);
context.addSubcontext(subcontextPath, subcontext);
context = subcontext;
}
return path.asSingleName();
}
Expand Down
Expand Up @@ -7,6 +7,7 @@
package com.evolveum.midpoint.repo.sqale.mapping;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.repo.sqale.qmodel.SqaleNestedMapping;
import com.evolveum.midpoint.repo.sqale.update.NestedContainerUpdateContext;
import com.evolveum.midpoint.repo.sqale.update.SqaleUpdateContext;
Expand Down Expand Up @@ -36,7 +37,8 @@ public ResolutionResult resolve(SqlQueryContext<?, Q, R> context) {
}

@Override
public NestedContainerUpdateContext<S, Q, R> resolve(SqaleUpdateContext<?, Q, R> context) {
public NestedContainerUpdateContext<S, Q, R> resolve(
SqaleUpdateContext<?, Q, R> context, ItemPath ignored) {
return new NestedContainerUpdateContext<>(context, mapping);
}
}
Expand Up @@ -6,6 +6,7 @@
*/
package com.evolveum.midpoint.repo.sqale.mapping;

import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.repo.sqale.update.SqaleUpdateContext;
import com.evolveum.midpoint.repo.sqlbase.mapping.ItemRelationResolver;
import com.evolveum.midpoint.repo.sqlbase.querydsl.FlexibleRelationalPathBase;
Expand All @@ -22,6 +23,7 @@ public interface SqaleItemRelationResolver<Q extends FlexibleRelationalPathBase<
* Resolves current query context to a new context (mapping is always part of context).
* The information about the resolved item is captured in the instance resolver already
* in a manner that is specific for various types of resolution (JOIN or nested mapping).
* Optional {@link ItemPath} is provided for cases when container ID is necessary.
*/
SqaleUpdateContext<?, ?, ?> resolve(SqaleUpdateContext<?, Q, R> context);
SqaleUpdateContext<?, ?, ?> resolve(SqaleUpdateContext<?, Q, R> context, ItemPath itemPath);
}

This file was deleted.

Expand Up @@ -14,7 +14,7 @@
import com.evolveum.midpoint.repo.sqale.filtering.RefTableItemFilterProcessor;
import com.evolveum.midpoint.repo.sqale.mapping.NestedMappingResolver;
import com.evolveum.midpoint.repo.sqale.mapping.SqaleItemSqlMapper;
import com.evolveum.midpoint.repo.sqale.mapping.TableRelationResolver;
import com.evolveum.midpoint.repo.sqale.mapping.ContainerTableRelationResolver;
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;
Expand Down Expand Up @@ -91,7 +91,7 @@ SqaleMappingMixin<S, Q, R> addContainerTableMapping(
// of course the join would be implemented in QOwnedBy
// BTW: adding OQ on refs is messy, we already have AOR and we would need AOQ for QAssignmentReferenceMapping too.
addRelationResolver(itemName,
new TableRelationResolver<>(containerMapping, joinPredicate));
new ContainerTableRelationResolver<>(containerMapping, joinPredicate));

addItemMapping(itemName, new SqaleItemSqlMapper<>(
ctx -> new ContainerTableDeltaProcessor<>(ctx, containerMapping)));
Expand Down
Expand Up @@ -40,8 +40,7 @@ protected QContainerMapping(
@NotNull Class<Q> queryType) {
super(tableName, defaultAliasName, schemaType, queryType);

// TODO how CID is mapped?
// addItemMapping(PrismConstants.T_ID, uuidMapper(q -> q.oid));
// CID is not mapped directly, it is used by path resolver elsewhere
}

@Override
Expand Down
Expand Up @@ -10,10 +10,9 @@
import com.querydsl.sql.dml.SQLUpdateClause;

import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.repo.sqale.qmodel.SqaleTableMapping;
import com.evolveum.midpoint.repo.sqale.qmodel.common.MContainer;
import com.evolveum.midpoint.repo.sqale.qmodel.common.QContainer;
import com.evolveum.midpoint.repo.sqlbase.JdbcSession;
import com.evolveum.midpoint.repo.sqlbase.mapping.QueryModelMapping;

/**
* Update context for owned containers stored in tables.
Expand All @@ -32,24 +31,28 @@ public class ContainerTableUpdateContext<S extends Containerable, Q extends QCon

private final Q path;
private final SQLUpdateClause update;
private final SqaleTableMapping<S, Q, R> mapping;

public ContainerTableUpdateContext(SqaleUpdateContext<?, ?, OR> parentContext,
JdbcSession jdbcSession, R row) {
super(parentContext, row);
public ContainerTableUpdateContext(
SqaleUpdateContext<?, ?, OR> parentContext,
SqaleTableMapping<S, Q, R> mapping) {
super(parentContext, null); // TODO what is row? fake row with owner + id
this.mapping = mapping;

path = null; // TODO mapping.defaultAlias(); mapping missing
path = mapping.defaultAlias();
// we create the update, but only use it if set methods are used
update = jdbcSession.newUpdate(path)
.where(path.isOwnedBy(parentContext.row()));
// TODO add CID condition after writing test that checks only the right container is changed :-)
}

public Q path() {
return path;
}

@Override
public QueryModelMapping<S, Q, R> mapping() {
return null; // TODO
public SqaleTableMapping<S, Q, R> mapping() {
return mapping;
}

public SQLUpdateClause update() {
Expand All @@ -63,7 +66,6 @@ public <P extends Path<T>, T> void set(P path, T value) {
/** Executes updates if applicable, nothing is done if set methods were not used. */
@Override
protected void finishExecutionOwn() {
System.out.println("ContainerTableUpdateContext EXECUTE");
if (!update.isEmpty()) {
update.execute();
}
Expand Down
Expand Up @@ -52,6 +52,5 @@ public <P extends Path<T>, T> void set(P path, T value) {
@Override
protected void finishExecutionOwn() {
// nothing to do, parent context has all the updates
System.out.println("NestedContainerUpdateContext EXECUTE");
}
}
Expand Up @@ -62,8 +62,7 @@ public abstract class SqaleUpdateContext<S, Q extends FlexibleRelationalPathBase
protected final JdbcSession jdbcSession;
protected final R row;

protected final Map<ItemPath, SqaleUpdateContext<?, ?, ?>> updateSubContexts =
new LinkedHashMap<>();
protected final Map<ItemPath, SqaleUpdateContext<?, ?, ?>> subcontexts = new LinkedHashMap<>();

public SqaleUpdateContext(
SqaleTransformerSupport sqlTransformerSupport,
Expand All @@ -79,6 +78,7 @@ public SqaleUpdateContext(
SqaleUpdateContext<?, ?, ?> parentContext,
R row) {
this.parentContext = parentContext;
// registering this with parent context must happen outside of constructor!
this.transformerSupport = parentContext.transformerSupport;
this.jdbcSession = parentContext.jdbcSession();
this.row = row;
Expand Down Expand Up @@ -117,15 +117,19 @@ public <TS, TR> TR insertOwnedRow(QOwnedByMapping<TS, TR, R> mapping, TS schemaO
return transformer.insert(schemaObject, row, jdbcSession);
}

public void addSubcontext(ItemPath itemPath, SqaleUpdateContext<?, ?, ?> subcontext) {
subcontexts.put(itemPath, subcontext);
}

/**
* Executes collected updates if applicable including all sub-contexts.
* Executes collected updates if applicable including all subcontexts.
* Implement the logic for one context in {@link #finishExecutionOwn()}.
* Updates for subtree are executed first.
*
* Insert and delete clauses were all executed by {@link ItemDeltaValueProcessor}s already.
*/
protected final void finishExecution() throws SchemaException, RepositoryException {
for (SqaleUpdateContext<?, ?, ?> sqaleUpdateContext : updateSubContexts.values()) {
for (SqaleUpdateContext<?, ?, ?> sqaleUpdateContext : subcontexts.values()) {
sqaleUpdateContext.finishExecution();
}
finishExecutionOwn();
Expand Down

0 comments on commit c17a0c7

Please sign in to comment.