Search in sources :

Example 26 with SketchEdge

use of easik.sketch.edge.SketchEdge in project fql by CategoricalData.

the class MySQLExporter method createConstraint.

/**
 * @param cd
 * @param id
 *
 * @return
 */
@Override
public List<String> createConstraint(final CommutativeDiagram<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> cd, final String id) {
    final List<String> sql = new LinkedList<>();
    final List<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = cd.getPaths();
    final EntityNode dom = paths.get(0).getDomain();
    final StringBuilder proc = new StringBuilder("");
    final List<String> declarations = new LinkedList<>();
    final List<String> values = new LinkedList<>();
    final List<String> args = new LinkedList<>();
    final List<String> params = new LinkedList<>();
    int targetNum = 0;
    for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : paths) {
        ++targetNum;
        final LinkedList<SketchEdge> tmpPath = new LinkedList<>(path.getEdges());
        tmpPath.removeFirst();
        final String fk = "_path" + targetNum + "fk";
        args.add(fk + ' ' + pkType());
        params.add("NEW." + quoteId(tableFK(path.getFirstEdge())));
        declarations.add("_cdTarget" + targetNum);
        if (tmpPath.size() == 0) {
            values.add("    SELECT " + fk + " INTO _cdTarget" + targetNum + ';' + lineSep);
        } else {
            values.add("    SELECT " + qualifiedFK(path.getLastEdge()) + " INTO _cdTarget" + targetNum + " FROM " + joinPath(tmpPath, false) + " WHERE " + qualifiedPK(tmpPath.getFirst().getSourceEntity()) + " = " + fk + ';' + lineSep);
        }
    }
    proc.append("CREATE PROCEDURE ").append(quoteId("commutativeDiagram" + id)).append('(').append(EasikTools.join(", ", args)).append(") BEGIN").append(lineSep).append("       DECLARE ").append(EasikTools.join(", ", declarations)).append(' ').append(pkType()).append(';').append(lineSep).append(EasikTools.join("", values)).append("       IF").append(lineSep);
    for (int i = 2; i <= targetNum; i++) {
        proc.append("               NOT (_cdTarget1 <=> _cdTarget").append(i).append(')');
        if (i < targetNum) {
            proc.append(" OR");
        }
        proc.append(lineSep);
    }
    proc.append("       THEN CALL constraint_failure('Commutative diagram constraint failure.');").append(lineSep).append("       END IF;").append(lineSep).append("END");
    addFail = true;
    sql.addAll(delimit("$$", proc));
    addTrigger(dom, "BEFORE INSERT", "CALL " + quoteId("commutativeDiagram" + id) + '(' + EasikTools.join(", ", params) + ')');
    return sql;
}
Also used : LinkedList(java.util.LinkedList) LimitConstraint(easik.model.constraint.LimitConstraint) EqualizerConstraint(easik.model.constraint.EqualizerConstraint) ProductConstraint(easik.model.constraint.ProductConstraint) SumConstraint(easik.model.constraint.SumConstraint) PullbackConstraint(easik.model.constraint.PullbackConstraint) EntityNode(easik.sketch.vertex.EntityNode) SketchGraphModel(easik.sketch.util.graph.SketchGraphModel) SketchFrame(easik.ui.SketchFrame) SketchEdge(easik.sketch.edge.SketchEdge) ModelPath(easik.model.path.ModelPath) Sketch(easik.sketch.Sketch)

Example 27 with SketchEdge

use of easik.sketch.edge.SketchEdge in project fql by CategoricalData.

the class MySQLExporter method createConstraint.

/**
 * @param constraint
 * @param id
 *
 * @return
 */
@Override
public List<String> createConstraint(final EqualizerConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> constraint, final String id) {
    final List<String> sql = new LinkedList<>();
    final EntityNode eq = constraint.getEqualizerEntity();
    final EntityNode source = constraint.getSourceEntity();
    final EntityNode target = constraint.getTargetEntity();
    final InjectiveEdge projEdge = (InjectiveEdge) constraint.getProjection().getFirstEdge();
    final List<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = constraint.getEqualizerPaths();
    final String insConName = "eqCon" + id + "InsUpd" + cleanId(source);
    final Collection<String> args = new LinkedList<>();
    final Collection<String> params = new LinkedList<>();
    args.add("_newId " + pkType());
    params.add("NEW." + quoteId(tablePK(source)));
    // commented out by Sarah van der Laan -- caused error in generated SQL
    // file (invalid foreign keys)
    /**
     * for (final SketchEdge shadow : source.getShadowEdges()) {
     * args.add(quoteId("NEW_shadow_" + tableFK(shadow)) + ' ' + pkType());
     * params.add("NEW." + quoteId(tableFK(shadow))); }
     */
    final StringBuilder proc = new StringBuilder(500);
    proc.append("CREATE PROCEDURE ").append(quoteId(insConName)).append('(').append(EasikTools.join(", ", args)).append(") BEGIN").append(lineSep);
    proc.append("   DECLARE _path0Id");
    // Add a variable for each path, _path0Id, _path1Id, etc.:
    for (int i = 1; i < paths.size(); i++) {
        proc.append(", _path").append(i).append("Id");
    }
    proc.append(' ').append(pkType()).append(';').append(lineSep);
    final String sourcePK = qualifiedPK(source);
    final String targetPK = qualifiedPK(target);
    final String newPK = "_newId";
    int i = 0;
    for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> p : paths) {
        proc.append("   SELECT ").append(targetPK).append(" INTO _path").append(i).append("Id").append(lineSep).append("           FROM ").append(joinPath(p)).append(lineSep).append("           WHERE ").append(sourcePK).append(" = ").append(newPK).append(';').append(lineSep);
        ++i;
    }
    // Build equality clause, such as: _path0Id IS DISTINCT FROM _path1Id OR
    // _path0Id IS DISTINCT FROM _path2Id OR ...
    proc.append("   IF NOT (_path0Id <=> _path1Id)");
    for (int j = 2; j < paths.size(); j++) {
        proc.append(" OR NOT (_path0Id <=> _path").append(j).append("Id)");
    }
    proc.append(" THEN").append(lineSep).append(// delete it from the equalizer (if it's there)
    "               DELETE FROM ").append(quoteId(eq)).append(" WHERE ").append(qualifiedFK(projEdge)).append(" = ").append(newPK).append(';').append(lineSep).append("       ELSEIF (SELECT COUNT(*) FROM ").append(quoteId(eq)).append(" WHERE ").append(qualifiedFK(projEdge)).append(" = ").append(newPK).append(") = 0 THEN").append(lineSep).append(// add it:
    "               ");
    /*
		 * Deal with intermediate nodes in projection Federico Mora
		 */
    ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path = constraint.getProjection();
    final SketchEdge[] edges = path.getEdges().toArray(new SketchEdge[path.getEdges().size()]);
    for (int j = edges.length - 1; j > 0; j--) {
        final EntityNode s = edges[j].getSourceEntity();
        if (j == edges.length - 1) {
            // after s there used to be dest.getShadowEdges();
            proc.append(insertInto(false, s, null, null, Collections.singletonList(quoteId(tableFK(edges[j]))), Collections.singletonList("_newId")));
        } else {
            // after source there used to be dest.getShadowEdges();
            proc.append(insertInto(false, s, null, null, Collections.singletonList(quoteId(tableFK(edges[j]))), Collections.singletonList("LAST_INSERT_ID()")));
        }
    }
    // done - deal with intermediate nodes in projection
    // after eq there used to be dest.getShadowEdges();
    proc.append("               ").append(insertInto(true, eq, null, null, Collections.singletonList(quoteId(tableFK(projEdge))), Collections.singletonList("LAST_INSERT_ID()"))).append("       END IF;").append(lineSep).append("END").append(lineSep);
    sql.add(proc.toString());
    // Create the trigger for inserting into the source table:
    final String call = "CALL " + quoteId(insConName) + '(' + EasikTools.join(", ", params) + ')';
    addTrigger(source, "AFTER INSERT", call);
    addTrigger(source, "AFTER UPDATE", call);
    // If the projection isn't a cascading edge, cascade:
    if (projEdge.getCascading() != SketchEdge.Cascade.CASCADE) {
        addTrigger(source, "BEFORE DELETE", "DELETE FROM " + quoteId(eq) + " WHERE " + qualifiedFK(projEdge) + " = OLD." + quoteId(tablePK(source)));
    }
    // Federico Mora
    ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> p = constraint.getProjection();
    StringBuilder proc1 = new StringBuilder(500);
    proc1.append("CREATE PROCEDURE ").append("Update" + constraint.getID() + "Proj").append("() BEGIN").append(lineSep);
    // making the update string which is used by all the delete
    // procedures.
    final LinkedList<SketchEdge> egs = p.getEdges();
    if (egs.size() >= 2) {
        Iterator<SketchEdge> iter = egs.iterator();
        SketchEdge e = iter.next();
        proc1.append("   UPDATE ").append(leftJoinPath(p)).append(lineSep);
        proc1.append("   SET");
        while (iter.hasNext()) {
            SketchEdge ske = iter.next();
            proc1.append(" " + quoteId(ske.getSourceEntity()) + ".BC" + constraint.getID() + " = " + false + ",");
        }
        proc1.delete(proc1.length() - 1, proc1.length());
        proc1.append(" WHERE " + qualifiedFK(e) + " IS NULL;" + lineSep);
        proc1.append("END");
        sql.add(proc1.toString());
        // Now create the triggers to call the new procedure
        addTrigger(p.getCoDomain(), "AFTER UPDATE", "CALL " + quoteId("Update" + constraint.getID() + "Proj") + "()");
    }
    return delimit("$$", sql);
}
Also used : LinkedList(java.util.LinkedList) LimitConstraint(easik.model.constraint.LimitConstraint) EqualizerConstraint(easik.model.constraint.EqualizerConstraint) ProductConstraint(easik.model.constraint.ProductConstraint) SumConstraint(easik.model.constraint.SumConstraint) PullbackConstraint(easik.model.constraint.PullbackConstraint) EntityNode(easik.sketch.vertex.EntityNode) SketchGraphModel(easik.sketch.util.graph.SketchGraphModel) SketchFrame(easik.ui.SketchFrame) InjectiveEdge(easik.sketch.edge.InjectiveEdge) SketchEdge(easik.sketch.edge.SketchEdge) ModelPath(easik.model.path.ModelPath) Sketch(easik.sketch.Sketch)

Example 28 with SketchEdge

use of easik.sketch.edge.SketchEdge in project fql by CategoricalData.

the class XSDExporter method createConstraint.

/**
 * Add an annotation explaining the sum constraint and effect the isAs.
 * <p/>
 * Today, this has two parts. First the annotation is truly just
 * documentation in this case. The second part of the constraint creation,
 * where the isA parts are added as elements of the type suffices to explain
 * everything that is needed. In the standard sum constraint in
 * constraints.easik gives this annotation:
 *
 * <pre>
 * &lt;xs:annotation>
 *  &lt;xs:documentation>
 *     Sum is a disjoint generalization of Summand1 and Summand2 and Summand3
 *   &lt;/xs:documentation>
 * &lt;/xs:annotation>
 * </pre>
 * <p/>
 * Each of the Summand entities have an "isA" relationship to the Sum entity
 * at the start of the diagram, so this is reflected in the typing. First,
 * an element of each Summand type is added to the target of the "isA"
 * relationship. Second, since there is no need for a separate element in
 * the schema for the Summand entity, its element is removed from the sketch
 * entity.
 *
 * @param sum
 *            the summand diagram constraint.
 * @todo Why not do this with standard isA relationships as well?
 */
private static void createConstraint(final SumConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> sum) {
    final Map<String, StringBuilder> codMap = new HashMap<>(10);
    final Map<String, XSDType> codToXMLType = new HashMap<>(10);
    XSDChoiceCompositor summands = new XSDChoiceCompositor(new ArrayList<XSDAbstractElement>(sum.getPaths().size()));
    String cdTypeName = "";
    XSDComplexType lastCodomainType = null;
    for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : sum.getPaths()) {
        final EntityNode coDomain = path.getCoDomain();
        final EntityNode dom = path.getDomain();
        final String coDomainName = coDomain.getName();
        final StringBuilder coDomainAnnotation;
        if (codMap.containsKey(coDomainName)) {
            coDomainAnnotation = codMap.get(coDomainName);
            coDomainAnnotation.append(" and ").append(dom.getName());
        } else {
            coDomainAnnotation = new StringBuilder(100);
            coDomainAnnotation.append(coDomain.getName()).append(" is a disjoint generalization of ").append(dom.getName());
        }
        final XSDComplexType codomainType = (XSDComplexType) coDomain.getXsdType();
        if ((null != lastCodomainType) && !cdTypeName.equals(codomainType.getName())) {
            if (!summands.isEmpty()) {
                lastCodomainType.addAtom(summands);
                summands = new XSDChoiceCompositor(new ArrayList<XSDAbstractElement>(sum.getPaths().size()));
            }
        }
        lastCodomainType = codomainType;
        cdTypeName = codomainType.getName();
        codToXMLType.put(coDomainName, codomainType);
        codMap.put(coDomainName, coDomainAnnotation);
        final XSDElement element = dom.getXsdElement();
        element.setParent(coDomain.getXsdElement());
        summands.addSubElement(element);
        dom.setXsdElement(null);
    }
    if (null != lastCodomainType) {
        if (!summands.isEmpty()) {
            lastCodomainType.addAtom(summands);
            summands = null;
        }
    }
    for (final Map.Entry<String, StringBuilder> entry : codMap.entrySet()) {
        final XSDType typ = codToXMLType.get(entry.getKey());
        typ.addAnnotation(new XSDAnnotation(entry.getValue().toString()));
    }
}
Also used : HashMap(java.util.HashMap) XSDAbstractElement(easik.xml.xsd.nodes.elements.XSDAbstractElement) ArrayList(java.util.ArrayList) XSDElement(easik.xml.xsd.nodes.elements.XSDElement) XSDType(easik.xml.xsd.nodes.types.XSDType) SketchGraphModel(easik.sketch.util.graph.SketchGraphModel) EntityNode(easik.sketch.vertex.EntityNode) SketchFrame(easik.ui.SketchFrame) SketchEdge(easik.sketch.edge.SketchEdge) Sketch(easik.sketch.Sketch) XSDChoiceCompositor(easik.xml.xsd.nodes.elements.XSDChoiceCompositor) XSDAnnotation(easik.xml.xsd.nodes.XSDAnnotation) HashMap(java.util.HashMap) Map(java.util.Map) XSDComplexType(easik.xml.xsd.nodes.types.XSDComplexType)

Example 29 with SketchEdge

use of easik.sketch.edge.SketchEdge in project fql by CategoricalData.

the class XSDExporter method createConstraint.

/**
 * Add an annotation explaining the pullback.
 * <p/>
 * Today, this is simply done by creating an annotation. For example in the
 * standard pullback constraint in constraints.easik gives this annotation:
 *
 * <pre>
 * &lt;xs:annotation>
 *  &lt;xs:documentation>
 *     ForAll.elemA in B, ForAll.elemB in C :
 *     elemA.f1 in A=elemB.isA_1 in A
 *     ==> Exists.p=(elemA,elemB) in Pullback
 *   &lt;/xs:documentation>
 * &lt;/xs:annotation>
 * </pre>
 *
 * @param pb
 *            the product diagram constraint.
 */
private void createConstraint(final PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> pb) {
    final List<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = pb.getPaths();
    final EntityNode dom = paths.get(0).getDomain();
    final XSDType domType = dom.getXsdType();
    final List<String> elts = new ArrayList<>(paths.size());
    @SuppressWarnings("unused") final String keyrefName = Easik.getInstance().getSettings().getProperty("xml_keyref_name");
    final List<String> values = new ArrayList<>();
    final List<String> equalities = new ArrayList<>();
    // WPBEDIT CF2012
    for (int i = 0; i < pb.getWidth(); i++) {
        final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path = pb.getFullPath(i);
        final LinkedList<SketchEdge> tmpPath = new LinkedList<>(path.getEdges());
        tmpPath.removeFirst();
        values.add("ForAll.elem" + i + " in " + xmlPBJoinPath(tmpPath, false));
        equalities.add("elem" + i + '.' + xmlPBelemJoinPath(tmpPath, true));
        elts.add("elem" + i);
    }
    final String valdocumentation = EasikTools.join(", ", values);
    final String equalDoc = EasikTools.join("=", equalities);
    final String elements = "==> Exists.p=(" + EasikTools.join(",", elts) + ") in " + dom.getName();
    domType.addAnnotation(new XSDAnnotation(valdocumentation + " : " + lineSep + equalDoc + lineSep + elements));
}
Also used : ArrayList(java.util.ArrayList) LimitConstraint(easik.model.constraint.LimitConstraint) EqualizerConstraint(easik.model.constraint.EqualizerConstraint) ProductConstraint(easik.model.constraint.ProductConstraint) SumConstraint(easik.model.constraint.SumConstraint) PullbackConstraint(easik.model.constraint.PullbackConstraint) ModelConstraint(easik.model.constraint.ModelConstraint) LinkedList(java.util.LinkedList) EntityNode(easik.sketch.vertex.EntityNode) XSDType(easik.xml.xsd.nodes.types.XSDType) SketchGraphModel(easik.sketch.util.graph.SketchGraphModel) SketchFrame(easik.ui.SketchFrame) SketchEdge(easik.sketch.edge.SketchEdge) ModelPath(easik.model.path.ModelPath) Sketch(easik.sketch.Sketch) XSDAnnotation(easik.xml.xsd.nodes.XSDAnnotation)

Example 30 with SketchEdge

use of easik.sketch.edge.SketchEdge in project fql by CategoricalData.

the class XSDExporter method xmlPBJoinPath.

/**
 * protected method to assist in building "pullbackpath" strings for the
 * pullback constraint annotations
 *
 * @param inEdges
 *            List of sketchedges
 * @param includeLast
 *            Include the last or not
 * @return path like string
 */
protected String xmlPBJoinPath(final List<SketchEdge> inEdges, final boolean includeLast) {
    final LinkedList<SketchEdge> edges = new LinkedList<>(inEdges);
    final StringBuilder joinClause = new StringBuilder(quoteId(edges.get(0).getSourceEntity().getName()));
    if (!includeLast && !edges.isEmpty()) {
        edges.removeLast();
    }
    for (final SketchEdge e : edges) {
        final EntityNode target = e.getTargetEntity();
        joinClause.append('(').append(e.getName()).append(")->").append(target.getName());
    }
    return joinClause.toString();
}
Also used : SketchEdge(easik.sketch.edge.SketchEdge) LinkedList(java.util.LinkedList) EntityNode(easik.sketch.vertex.EntityNode)

Aggregations

SketchEdge (easik.sketch.edge.SketchEdge)51 EntityNode (easik.sketch.vertex.EntityNode)45 Sketch (easik.sketch.Sketch)31 SketchGraphModel (easik.sketch.util.graph.SketchGraphModel)31 SketchFrame (easik.ui.SketchFrame)30 LinkedList (java.util.LinkedList)22 LimitConstraint (easik.model.constraint.LimitConstraint)17 ProductConstraint (easik.model.constraint.ProductConstraint)16 PullbackConstraint (easik.model.constraint.PullbackConstraint)16 SumConstraint (easik.model.constraint.SumConstraint)16 EqualizerConstraint (easik.model.constraint.EqualizerConstraint)13 ModelConstraint (easik.model.constraint.ModelConstraint)13 ArrayList (java.util.ArrayList)11 ModelPath (easik.model.path.ModelPath)9 LinkedHashSet (java.util.LinkedHashSet)9 InjectiveEdge (easik.sketch.edge.InjectiveEdge)7 UniqueIndexable (easik.model.keys.UniqueIndexable)5 XSDAnnotation (easik.xml.xsd.nodes.XSDAnnotation)5 XSDType (easik.xml.xsd.nodes.types.XSDType)5 EasikType (easik.database.types.EasikType)4