/******************************************************************************* * Copyright (c) 2007, 2018 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.impl.query; import org.simantics.db.RelationInfo; import org.simantics.db.exception.DatabaseException; import org.simantics.db.impl.graph.ReadGraphImpl; import org.simantics.db.impl.procedure.InternalProcedure; import org.simantics.db.request.RequestFlags; public final class RelationInfoQuery extends UnaryQueryP { RelationInfoQuery(int resource) { super(resource); } @Override public final void removeEntry(QueryProcessor provider) { provider.cache.remove(this); } private static void computeAssertions(ReadGraphImpl graph, int r, final boolean isFinal, final boolean isFunctional, RelationInfoQuery parent, final InternalProcedure procedure) throws DatabaseException { QueryProcessor processor = graph.processor; final int isUsedInAssertion = processor.getHasPredicateInverse(); assert(isUsedInAssertion != 0); QueryCache.runnerDirectObjects(graph, r, isUsedInAssertion, parent, null, new IntProcedure() { boolean done = false; @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { if(done) return; done = true; RelationInfo result = new RelationInfo(r, isFunctional, isFinal, true); procedure.execute(graph, result); } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { if(done) return; done = true; RelationInfo result = new RelationInfo(r, isFunctional, isFinal, false); procedure.execute(graph, result); } @Override public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException { if(done) return; done = true; DatabaseException e = new DatabaseException("Internal error in RelationInfoQuery"); procedure.exception(graph, e); } }); } public static void computeForEach(ReadGraphImpl graph, int r, RelationInfoQuery entry, InternalProcedure procedure_) throws DatabaseException { InternalProcedure procedure = entry != null ? entry : procedure_; QueryProcessor provider = graph.processor; final int superRelationOf = provider.getSuperrelationOf(); assert(superRelationOf != 0); IntSet direct = QueryCache.resultDirectPredicates(graph, r, entry, null); IntSet types = QueryCache.resultTypes(graph, r, entry, null); computeAssertions(graph, r, !direct.contains(superRelationOf), types.contains(graph.processor.getFunctionalRelation()), entry, procedure); if(entry != null) entry.performFromCache(graph, procedure_); } @Override public void compute(ReadGraphImpl graph, final InternalProcedure procedure) throws DatabaseException { computeForEach(graph, id, this, procedure); } @Override public String toString() { return "RelationInfoQuery[" + id + "]"; } @Override public int type() { return RequestFlags.IMMEDIATE_UPDATE; } @Override public void serializeValue(QuerySerializer serializer) { RelationInfo ri = getResult(); serializer.addResource(ri.predicate); serializer.add(ri.isFunctional ? (byte)1 : 0); serializer.add(ri.isFinal ? (byte)1 : 0); serializer.add(ri.isAsserted ? (byte)1 : 0); } }