use of easik.ui.SketchFrame in project fql by CategoricalData.
the class MySQLExporter method createConstraint.
/**
* @param constraint
* @param id
*
* @return
*/
@Override
public List<String> createConstraint(final LimitConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> constraint, final String id) {
final List<String> sql = new LinkedList<>();
StringBuilder proc = new StringBuilder(500);
final List<String> declarations = new LinkedList<>();
final List<String> values = new LinkedList<>();
final List<String> args = new LinkedList<>();
final List<String> params = new LinkedList<>();
// getting the paths involved in this limit constraint
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> coneAB = constraint.getCone().AB;
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> coneBC = constraint.getCone().BC;
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> coneAC = constraint.getCone().AC;
// TODO this should be in the LimitConstraint
List<SketchEdge> tmpEdges = coneAB.getEdges();
tmpEdges.addAll(coneBC.getEdges());
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> coneABC = new ModelPath<>(tmpEdges);
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> limitConeAB = constraint.getLimitCone1().AB;
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> limitCone1BC = constraint.getLimitCone1().BC;
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> limitCone2BC = constraint.getLimitCone2().BC;
tmpEdges = limitConeAB.getEdges();
tmpEdges.addAll(limitCone1BC.getEdges());
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> limitCone1ABC = new ModelPath<>(tmpEdges);
tmpEdges = limitConeAB.getEdges();
tmpEdges.addAll(limitCone2BC.getEdges());
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> limitCone2ABC = new ModelPath<>(tmpEdges);
ArrayList<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = new ArrayList<>();
paths.add(coneABC);
paths.add(coneAC);
paths.add(limitCone1ABC);
paths.add(coneAB);
paths.add(limitCone2ABC);
// would add coneAC, but it's already been added
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("limitConstraint" + 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);
// cone commutativity check
proc.append(" NOT (_cdTarget1 <=> _cdTarget2) OR");
proc.append(lineSep);
// limitCone1 commutativity check
proc.append(" NOT (_cdTarget3 <=> _cdTarget4) OR");
proc.append(lineSep);
// limitCone2 commutativity check
proc.append(" NOT (_cdTarget5 <=> _cdTarget2)");
proc.append(lineSep);
proc.append(" THEN CALL constraint_failure('Limit constraint failure.');").append(lineSep).append(" END IF;").append(lineSep).append("END");
addFail = true;
sql.addAll(delimit("$$", proc));
// cast because we will only do this in sketches
addTrigger(constraint.getCone().getA(), "BEFORE INSERT", "CALL " + quoteId("limitConstraint" + id) + '(' + EasikTools.join(", ", params) + ')');
return sql;
}
use of easik.ui.SketchFrame in project fql by CategoricalData.
the class MySQLExporter method pbAfterInsertProcs.
/**
* @param sql
* @param id
* @param constraint
* @param thisPath
* @param thisFirstPath
* @param index
*/
private void pbAfterInsertProcs(final List<String> sql, final String id, final PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> constraint, final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> thisPath, final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> thisFirstPath, int index) {
final EntityNode source = thisPath.getDomain();
final EntityNode pb = thisFirstPath.getDomain();
final EntityNode target = thisPath.getCoDomain();
final String insConName = "pullbackConstraint" + id + "Insert" + 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);
// trigger body
// omitting last
final String thisJoinPath = joinPath(thisPath, false);
// edge
String lastJoinOn = "JOIN " + quoteId(target) + " ON " + qualifiedFK(thisPath.getLastEdge()) + " = " + qualifiedPK(target);
for (int i = 0; i < constraint.getWidth(); i++) {
if (i == index) {
continue;
}
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> otherPath = constraint.getTargetPath(i);
lastJoinOn += " AND ";
lastJoinOn += qualifiedFK(otherPath.getLastEdge()) + " = " + qualifiedPK(target);
}
proc.append("\tIF (SELECT COUNT(*) FROM (").append(thisJoinPath);
for (int i = 0; i < constraint.getWidth(); i++) {
if (i == index) {
continue;
}
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> otherPath = constraint.getTargetPath(i);
proc.append(", ").append(joinPath(otherPath, false));
}
proc.append(") ").append(lastJoinOn).append(" WHERE ").append(qualifiedPK(source)).append(" = _newId) > 0 THEN").append(lineSep);
// constraint condition met
SketchEdge[] edges;
for (int i = 0; i < constraint.getWidth(); i++) {
if (i == index) {
continue;
}
final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> otherPath = constraint.getTargetPath(i);
final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> otherFirstPath = constraint.getProjectionPath(i);
final LinkedList<SketchEdge> sketchEdgeLinkedList = otherFirstPath.getEdges();
edges = sketchEdgeLinkedList.toArray(new SketchEdge[sketchEdgeLinkedList.size()]);
if (edges.length >= 2) {
final String joinOn = "JOIN " + quoteId(target) + " ON " + qualifiedFK(thisPath.getLastEdge()) + " = " + qualifiedPK(target) + " AND " + qualifiedFK(otherPath.getLastEdge()) + " = " + qualifiedPK(target);
// proc.append("\t\tIF (SELECT COUNT(*) FROM
// (").append(joinPath(sketchEdgeLinkedList, true));
proc.append("\t\tIF (SELECT COUNT(*) FROM (").append(joinPath(constraint.getFullPath(i).getEdges(), false));
// TODO might have the same bug if the target path is longer
// than 1, check this
proc.append(", ").append(thisJoinPath).append(") ").append(joinOn).append(" WHERE ").append(qualifiedPK(source)).append(" = _newId) = 0 THEN").append(lineSep);
final LinkedList<SketchEdge> partialPath = new LinkedList<>(otherPath.getEdges());
for (int j = edges.length - 1; j > 0; j--) {
final EntityNode s = edges[j].getSourceEntity();
final EntityNode t = edges[j].getTargetEntity();
// after s there used to be dest.getShadowEdges();
proc.append("\t\t\t").append(insertInto(// SELECT
true, // SELECT
s, // SELECT
qualifiedPK(t), // FROM:
'(' + joinPath(partialPath, false) + ", " + thisJoinPath + ") " + joinOn + " WHERE " + qualifiedPK(source) + " = _newId", Collections.singletonList(quoteId(tableFK(edges[j]))), null));
partialPath.addFirst(edges[j]);
}
proc.append("\t\tEND IF;").append(lineSep);
}
}
final LinkedList<SketchEdge> firstPathEdges = thisFirstPath.getEdges();
edges = firstPathEdges.toArray(new SketchEdge[firstPathEdges.size()]);
final LinkedList<SketchEdge> partialPath = new LinkedList<>(thisPath.getEdges());
for (int i = edges.length - 1; i > 0; i--) {
final SketchEdge e = edges[i];
final EntityNode s = e.getSourceEntity();
final EntityNode t = e.getTargetEntity();
// after s there used to be dest.getShadowEdges();
proc.append("\t\t").append(insertInto(true, s, qualifiedPK(t), joinPath(partialPath) + " WHERE " + qualifiedPK(source) + " = _newId", Collections.singletonList(quoteId(tableFK(e))), null));
partialPath.addFirst(e);
}
final EntityNode firstStop = thisFirstPath.getFirstCoDomain();
final List<String> cols = new LinkedList<>();
cols.add(quoteId(tableFK(thisFirstPath.getFirstEdge())));
String tmpStr1 = qualifiedPK(firstStop);
LinkedList<SketchEdge> tmpPath = new LinkedList<>(constraint.getFullPath(0).getEdges());
tmpPath.removeFirst();
String tmpStr2 = '(' + joinPath(tmpPath, false);
for (int i = 0; i < constraint.getWidth(); i++) {
final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> otherFirstPath = constraint.getProjectionPath(i);
final EntityNode otherFirstStop = otherFirstPath.getFirstCoDomain();
if (otherFirstPath != thisFirstPath) {
tmpStr1 += ", " + qualifiedPK(otherFirstStop);
cols.add(quoteId(tableFK(otherFirstPath.getFirstEdge())));
}
if (i > 0) {
tmpPath = new LinkedList<>(constraint.getFullPath(i).getEdges());
tmpPath.removeFirst();
tmpStr2 += ", " + joinPath(tmpPath, false);
}
}
// after pb there used to be dest.getShadowEdges();
proc.append("\t\t").append(insertInto(true, pb, tmpStr1, tmpStr2 + ") " + lastJoinOn + " WHERE " + qualifiedPK(source) + " = _newId", cols, null));
// end constraint condition met
proc.append("\tEND IF;");
// end trigger body
proc.append(lineSep).append("END");
sql.add(proc.toString());
// Now create the trigger to call the new procedure
addTrigger(source, "AFTER INSERT", "CALL " + quoteId(insConName) + '(' + EasikTools.join(", ", params) + ')');
}
use of easik.ui.SketchFrame in project fql by CategoricalData.
the class MySQLExporter method createTable.
/**
* @param table
* @param includeRefs
*
* @return
*/
@Override
public List<String> createTable(final EntityNode table, final boolean includeRefs) {
final StringBuilder tableDef = new StringBuilder("CREATE TABLE ");
tableDef.append(quoteId(table)).append(" (").append(lineSep);
tableDef.append('\t').append(quoteId(tablePK(table))).append(' ').append(pkType()).append(" PRIMARY KEY AUTO_INCREMENT");
for (final EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> attr : table.getEntityAttributes()) {
// FIXME -- what about NOT NULL, etc. on the column? Defaults?
tableDef.append(',').append(lineSep).append('\t').append(quoteId(attr.getName())).append(' ').append(dbDriver.getTypeString(attr.getType()));
}
// includeRefs set)
for (final SketchEdge edge : table.getOutgoingEdges()) {
tableDef.append(',').append(lineSep).append('\t').append(quoteId(tableFK(edge))).append(' ').append(pkType());
if (!edge.isPartial()) {
tableDef.append(" NOT NULL");
}
if (edge.isInjective()) {
tableDef.append(" UNIQUE");
}
if (includeRefs) {
tableDef.append(',').append(lineSep).append(" FOREIGN KEY (").append(quoteId(tableFK(edge))).append(") REFERENCES ").append(quoteId(edge.getTargetEntity())).append(" (").append(quoteId(tablePK(edge.getTargetEntity()))).append(')');
// Effectively
final String refMode = (edge.getCascading() == SketchEdge.Cascade.SET_NULL) ? "SET NULL" : (edge.getCascading() == SketchEdge.Cascade.CASCADE) ? "CASCADE" : "NO ACTION";
// the
// same
// as
// RESTRICT,
// but
// RESTRICT
// won't
// even
// work
// if
// cleaned
// up
// in
// the
// same
// transaction
tableDef.append(" ON DELETE ").append(refMode).append(" ON UPDATE ").append(refMode);
}
}
// Add the unique keys
for (final UniqueKey<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> key : table.getUniqueKeys()) {
tableDef.append(',').append(lineSep).append(" UNIQUE ").append(quoteId(table.getName() + '_' + key.getKeyName())).append(" (");
final List<String> keyCols = new LinkedList<>();
for (final UniqueIndexable elem : key.getElements()) {
if (elem instanceof SketchEdge) {
keyCols.add(quoteId(tableFK((SketchEdge) elem)));
} else {
// Probably an attribute
keyCols.add(quoteId(elem.getName()));
}
}
tableDef.append(EasikTools.join(", ", keyCols)).append(')');
}
// add hidden attributes last
for (final EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> attr : table.getHiddenEntityAttributes()) {
// Default is false so that when user adds rows manually we don't
// give option for hidden attributes
// and just leave them false
tableDef.append(',').append(lineSep).append('\t').append(quoteId(attr.getName())).append(' ').append(dbDriver.getTypeString(attr.getType())).append(" Default " + false);
}
// commented out by Sarah van der Laan -- caused error in generated SQL
// file (invalid foreign keys)
/**
* if (includeRefs) { // We need a copy of any sum tables' not-null
* columns (which are simply the // outgoing, non-partial edges) if this
* table is a summand; we shadow the // columns here, then handle
* propagating them in the SumConstraint triggers. for (final SketchEdge
* edge : table.getShadowEdges()) {
* tableDef.append(',').append(lineSep).append('\t').append(quoteId(tableFK(edge))).append('
* ').append(pkType()); tableDef.append(',').append(lineSep).append("
* FOREIGN KEY (").append(quoteId(tableFK(edge))).append(") REFERENCES
* ").append( quoteId(edge.getTargetEntity())).append("
* (").append(quoteId(tablePK(edge.getTargetEntity()))).append( ") ON
* DELETE SET NULL ON UPDATE SET NULL"); } }
*/
tableDef.append(lineSep).append(')').append(TABLE_OPTIONS).append($);
return Collections.singletonList(tableDef.toString());
}
use of easik.ui.SketchFrame in project fql by CategoricalData.
the class XSDExporter method createConstraint.
/**
* Add an annotation explaining the equalizer and effect the isA.
* <p/>
* Today, this has two parts. First the annotation. For example in the
* standard equalizer constraint in constraints.easik gives this annotation:
*
* <pre>
* <xs:annotation>
* <xs:documentation>
* Equalizer(f3); B(f4) ;C(f5) ;Codomain =
* Equalizer(f1); D(f2) ;Codomain
* </xs:documentation>
* </xs:annotation>
* </pre>
* <p/>
* In addition, the equalizer entity has an "isA" relationship to another
* entity at the start of the diagram, so this is reflected in the typing.
* First, an element of equalizer 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 equalizer entity, its element is removed from the
* sketch entity.
*
* @param eq
* the equalizer diagram constraint.
* @todo Why not do this with standard isA relationships as well?
* @todo The equalizer element should be added in some way so there is a
* "minoccurs" of zero.
* @todo The equalizer does not really need a "key" element, but what if
* other constraints refer to it.
*/
private void createConstraint(final EqualizerConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> eq) {
final List<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = eq.getEqualizerPaths();
final EntityNode equalizer = eq.getEqualizerEntity();
final XSDType domType = equalizer.getXsdType();
final String keyrefName = Easik.getInstance().getSettings().getProperty("xml_keyref_name");
final List<String> values = new ArrayList<>(paths.size());
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : paths) {
final LinkedList<SketchEdge> tmpPath = new LinkedList<>(path.getEdges());
tmpPath.removeFirst();
if (tmpPath.size() == 0) {
values.add(equalizer.getName() + '(' + path.getFirstEdge().getForeignKeyName(keyrefName) + ')');
} else {
values.add(equalizer.getName() + '(' + path.getFirstEdge().getForeignKeyName(keyrefName) + ')' + xmlJoinPath(tmpPath, true));
}
}
final EntityNode isaNode = paths.get(0).getDomain();
final XSDComplexType isaNodeType = (XSDComplexType) isaNode.getXsdType();
final XSDElement element = equalizer.getXsdElement();
element.setParent(isaNode.getXsdElement());
isaNodeType.addAtom(element);
equalizer.setXsdElement(null);
domType.addAnnotation(new XSDAnnotation(EasikTools.join(" = " + lineSep, values)));
}
use of easik.ui.SketchFrame in project fql by CategoricalData.
the class XSDExporter method createConstraint.
/**
* Add an annotation explaining the commutativity of the diagram.
* <p/>
* Today, this is simply done by creating an annotation. For example in the
* standard cd in constraints.easik gives this annotation:
*
* <pre>
* <xs:annotation>
* <xs:documentation>
* Domain(f1); A(f2) ;Codomain =
* Domain(f3); B(f4) ;Codomain
* </xs:documentation>
* </xs:annotation>
* </pre>
*
* @param cd
* the commutative diagram constraint.
*/
private void createConstraint(final CommutativeDiagram<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> cd) {
final List<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = cd.getPaths();
final EntityNode dom = paths.get(0).getDomain();
final XSDType domType = dom.getXsdType();
final String keyrefName = Easik.getInstance().getSettings().getProperty("xml_keyref_name");
final List<String> values = new ArrayList<>(paths.size());
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : paths) {
final LinkedList<SketchEdge> tmpPath = new LinkedList<>(path.getEdges());
tmpPath.removeFirst();
if (tmpPath.size() == 0) {
values.add(dom.getName() + '(' + path.getFirstEdge().getForeignKeyName(keyrefName) + ')');
} else {
values.add(dom.getName() + '(' + path.getFirstEdge().getForeignKeyName(keyrefName) + ')' + xmlJoinPath(tmpPath, true));
}
}
domType.addAnnotation(new XSDAnnotation(EasikTools.join(" = " + lineSep, values)));
}
Aggregations