use of easik.model.constraint.SumConstraint in project fql by CategoricalData.
the class DeletePathAction method actionPerformed.
/**
* Tests if the removal is valid and then removes the path from the
* constraint
*
* @param e
* The action event
*/
@Override
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
// If there is nothing seleceted then just do nothing
if (_theFrame.getInfoTreeUI().getInfoTree().isSelectionEmpty()) {
return;
}
// cancel operation
if (_theFrame.getMModel().isSynced()) {
int choice = JOptionPane.showConfirmDialog(_theFrame, "Warning: this sketch is currently synced with a db; continue and break synchronization?", "Warning!", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
if (choice == JOptionPane.CANCEL_OPTION) {
return;
}
}
// Get currently selected object
DefaultMutableTreeNode curSelected = (DefaultMutableTreeNode) _theFrame.getInfoTreeUI().getInfoTree().getSelectionPath().getLastPathComponent();
// Selection is a constraint
if (curSelected instanceof ModelPath) {
ModelConstraint<F, GM, M, N, E> curConstraint = (ModelConstraint<F, GM, M, N, E>) curSelected.getParent();
ArrayList<ModelPath<F, GM, M, N, E>> tempPaths = new ArrayList<>();
tempPaths.remove(curSelected);
boolean valid = false;
if (curConstraint instanceof SumConstraint) {
valid = _theFrame.getMModel().isSumConstraint(tempPaths);
// Replace previous path array list
if (valid) {
((SumConstraint<F, GM, M, N, E>) curConstraint).setPaths(tempPaths);
}
} else if (curConstraint instanceof ProductConstraint) {
valid = _theFrame.getMModel().isProductConstraint(tempPaths);
// Replace previous path array list
if (valid) {
((ProductConstraint<F, GM, M, N, E>) curConstraint).setPaths(tempPaths);
}
} else if (curConstraint instanceof CommutativeDiagram) {
valid = _theFrame.getMModel().isCommutativeDiagram(tempPaths);
// Replace previous path array list
if (valid) {
((CommutativeDiagram<F, GM, M, N, E>) curConstraint).setPaths(tempPaths);
}
} else {
JOptionPane.showMessageDialog(_theFrame, "You don't have a path selected that can be removed. \nPlease select another path and try again.", "No ModelConstraint Selected", JOptionPane.ERROR_MESSAGE);
return;
}
if (valid) {
ModelConstraint<F, GM, M, N, E> myConst = curConstraint;
// Remove old tree node
myConst.removeFromParent();
_theFrame.getInfoTreeUI().addConstraint(myConst);
// Referesh Tree
_theFrame.getInfoTreeUI().refreshTree(myConst);
_theFrame.getMModel().setDirty();
_theFrame.getMModel().setSynced(false);
} else {
JOptionPane.showMessageDialog(_theFrame, "Revoming this path would make the constraint invalid.\nPath was not removed", "Path Not Removed", JOptionPane.ERROR_MESSAGE);
}
} else // Selection is not a constraint
{
JOptionPane.showMessageDialog(_theFrame, "You don't have a path selected. \nPlease select a path and try again.", "No ModelConstraint Selected", JOptionPane.ERROR_MESSAGE);
}
}
use of easik.model.constraint.SumConstraint in project fql by CategoricalData.
the class MySQLExporter method createConstraint.
/**
* @param constraint
* @param id
*
* @return
*/
@Override
public List<String> createConstraint(final SumConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> constraint, final String id) {
final List<String> sql = new LinkedList<>();
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : constraint.getPaths()) {
final EntityNode dom = path.getDomain();
final EntityNode codo = path.getCoDomain();
final String baseConName = "sumConstraint" + id + cleanId(dom);
final StringBuilder proc = new StringBuilder(500);
proc.append("CREATE PROCEDURE ").append(quoteId(baseConName + "Delete")).append("(_deleteFK ").append(pkType()).append(") BEGIN").append(lineSep).append(" DELETE FROM ").append(quoteId(codo)).append(" WHERE ").append(qualifiedPK(codo)).append(" = ");
if (path.getEdges().size() == 1) {
proc.append("_deleteFK");
} else {
final LinkedList<SketchEdge> trailing = new LinkedList<>(path.getEdges());
trailing.removeFirst();
proc.append("(SELECT ").append(qualifiedFK(trailing.getLast())).append(" FROM ").append(joinPath(trailing, false)).append(" WHERE ").append(qualifiedPK(path.getFirstCoDomain())).append(" = _deleteFK)");
}
proc.append(';').append(lineSep).append("END");
sql.add(proc.toString());
addTrigger(dom, "AFTER DELETE", "CALL " + quoteId(baseConName + "Delete") + "(OLD." + quoteId(tableFK(path.getFirstEdge())) + ')');
final List<String> insertions = new LinkedList<>();
// after codo there used to be dest.getShadowEdges();
insertions.add(insertInto(false, codo, null, null, null, null));
final SketchEdge[] edges = path.getEdges().toArray(new SketchEdge[path.getEdges().size()]);
for (int i = edges.length - 1; i > 0; i--) {
final EntityNode source = edges[i].getSourceEntity();
// after source there used to be dest.getShadowEdges();
insertions.add(insertInto(false, source, null, null, Collections.singletonList(quoteId(tableFK(edges[i]))), Collections.singletonList("LAST_INSERT_ID()")));
}
insertions.add("SET NEW." + quoteId(tableFK(edges[0])) + " = LAST_INSERT_ID()");
addTrigger(dom, "BEFORE INSERT", insertions);
}
return delimit("$$", sql);
}
use of easik.model.constraint.SumConstraint in project fql by CategoricalData.
the class JDBCExporter method createConstraints.
/**
* Generates db constraints from the sketch constraints. This method is not
* generally overridden by drivers: the individual createConstraint(...)
* methods are called for each existing constraint.
*
* @return list of queries to create the constraints.
*/
protected List<String> createConstraints() {
final List<String> constraintSQL = new LinkedList<>();
final List<ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> constraints = new ArrayList<>(sketch.getConstraints().values());
int id = 0;
for (final ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> c : constraints) {
id++;
if (c instanceof CommutativeDiagram) {
constraintSQL.addAll(createConstraint((CommutativeDiagram<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c, String.valueOf(id)));
} else if (c instanceof ProductConstraint) {
constraintSQL.addAll(createConstraint((ProductConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c, String.valueOf(id)));
} else if (c instanceof PullbackConstraint) {
constraintSQL.addAll(createConstraint((PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c, String.valueOf(id)));
} else if (c instanceof EqualizerConstraint) {
constraintSQL.addAll(createConstraint((EqualizerConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c, String.valueOf(id)));
} else if (c instanceof SumConstraint) {
constraintSQL.addAll(createConstraint((SumConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c, String.valueOf(id)));
} else if (c instanceof LimitConstraint) {
constraintSQL.addAll(createConstraint((LimitConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c, String.valueOf(id)));
} else {
System.err.println("Unknown constraint type encountered: " + c.getClass());
}
}
return constraintSQL;
}
use of easik.model.constraint.SumConstraint in project fql by CategoricalData.
the class JDBCUpdateMonitor method insert.
/**
* Determines if insertion into a given table requires special handling due
* to constraints it may be in. As of now, special cases that may result
* from being in multiple constraints are not supported.
*
* @param table
* The table into which we wish to insert data
* @return Success of the insertion
*/
@Override
public boolean insert(final EntityNode table) {
final DialogOptions dOpts = getDialogOptions(table);
final String lineSep = EasikTools.systemLineSeparator();
// a set of column-value pairs of which we wish to force a specific
// value, leaving the user out
final Set<ColumnEntry> forced = new HashSet<>(10);
// contstraint. Tighten up?
for (final ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> c : table.getConstraints()) {
if (c instanceof SumConstraint) {
// of its foreign key, so remove it from the dialog's selection
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> sp : c.getPaths()) {
if (sp.getDomain() == table) {
// we force the value 0 to avoid out driver to kick back
// an error for having a null fKey
final String columnName = cn.tableFK(sp.getFirstEdge());
dOpts.fKeys.remove(columnName);
forced.add(new ColumnEntry(columnName, "0", new Int()));
break;
}
}
}
if (c instanceof CommutativeDiagram) {
// commute
if (c.getPaths().get(0).getDomain() == table) {
JOptionPane.showMessageDialog(null, "Be sure that the following paths commute:" + lineSep + EasikTools.join(lineSep, c.getPaths()), "Commutative diagram", JOptionPane.INFORMATION_MESSAGE);
try {
return promptAndInsert(table, dOpts, forced);
} catch (SQLException e) {
/*
* if(e instanceof com.mysql.jdbc.exceptions.jdbc4.
* MySQLIntegrityConstraintViolationException){
* //injective property violated
* JOptionPane.showMessageDialog(null, e.getMessage(),
* "Injective property violation",
* JOptionPane.ERROR_MESSAGE); }else{
*/
JOptionPane.showMessageDialog(null, "Not all of the following paths commute -- insert aborted!" + lineSep + EasikTools.join(lineSep, c.getPaths()), "Commutative diagram failure", JOptionPane.ERROR_MESSAGE);
// }
}
}
}
if (c instanceof PullbackConstraint) {
// happens, we want to let the user update the new record
if (((PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c).getTarget() != table) {
final EntityNode pullback = ((PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c).getSource();
try {
// get row count pre-insert
ResultSet result = dbd.executeQuery("SELECT COUNT(*) FROM " + pullback.getName() + " X");
result.next();
final int preRowCount = result.getInt(1);
if (!promptAndInsert(table, dOpts)) {
return false;
}
// get row count post-insert
result = dbd.executeQuery("SELECT COUNT(*) FROM " + pullback.getName() + " X");
result.next();
final int postRowCount = result.getInt(1);
// new row (the one with the highest primary ID)
if (postRowCount > preRowCount) {
result = dbd.executeQuery("SELECT MAX(" + cn.tablePK(pullback) + ") FROM " + pullback.getName() + " X");
result.next();
final int pk = result.getInt(1);
if (JOptionPane.showConfirmDialog(null, "New record in pullback table '" + pullback.getName() + "'. Enter column data?", "Insert column data?", JOptionPane.YES_NO_OPTION) == 0) {
updateRow(pullback, pk);
}
}
return true;
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, "Could not execute update. MYSQL Error output:\n" + e.getMessage());
}
}
}
if (c instanceof ProductConstraint) {
// inserting into the product.
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> sp : c.getPaths()) {
if (sp.getCoDomain() == table) {
final EntityNode product = sp.getDomain();
try {
if (!promptAndInsert(table, dOpts)) {
return false;
}
// get the new records from the product. They are
// any record who's fk to our INSERT factor matches
// the primary id of the last insert
ResultSet result = dbd.executeQuery("SELECT MAX(" + cn.tablePK(table) + ") FROM " + table.getName() + " X");
result.next();
final int newPK = result.getInt(1);
result = dbd.executeQuery("SELECT * FROM " + product.getName() + " WHERE " + cn.tableFK(sp.getFirstEdge()) + " = " + newPK);
// get count of new rows as result of INSERT
result.last();
final int newRows = result.getRow();
result.beforeFirst();
if ((newRows > 0) && (JOptionPane.showConfirmDialog(null, newRows + " new rows in product table '" + product.getName() + "'. Insert column data?", "Insert column data?", JOptionPane.YES_NO_OPTION) == 0)) {
while (result.next()) {
updateRow(product, result.getInt(1));
}
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
return true;
}
}
}
if (c instanceof LimitConstraint) {
// TRIANGLES TODO CF2012 Incomplete
}
}
try {
return promptAndInsert(table, dOpts, forced);
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, "Could not execute update. MYSQL Error output:\n" + e.getMessage());
System.err.println(e.getMessage());
return false;
}
}
use of easik.model.constraint.SumConstraint in project fql by CategoricalData.
the class SketchHandler method startElement.
/**
* Overloaded method that is called any time the start of an element is
* found
*
* @param namespace
* @see org.xml.sax.helpers.DefaultHandler
* @param localName
* @see org.xml.sax.helpers.DefaultHandler
* @param qName
* @see org.xml.sax.helpers.DefaultHandler
* @param atts
* @see org.xml.sax.helpers.DefaultHandler
*/
@Override
public void startElement(String namespace, String localName, String qName, Attributes atts) {
_currNode = qName;
if (qName.equals("entity")) {
String name = atts.getValue("name");
int x = Integer.parseInt(atts.getValue("x"));
int y = Integer.parseInt(atts.getValue("y"));
if (_entityNodes.containsKey(name)) {
System.err.println("Duplicate nodes found in XML");
return;
}
_newNode = new EntityNode(name, x, y, _theFrame.getMModel());
_entityNodes.put(name, _newNode);
_curNodeAtts = new LinkedHashMap<>();
} else if (qName.equals("attribute")) {
EasikType type;
// attributeType was created by old Easik versions, and is the SQL
// type signature
// (such as "VARCHAR(255)"). Easik now uses attributeTypeClass,
// containing the
// class name, and any number of extra attributes which
// EasikType.newType() uses to
// recreate the appropriate EasikType object.
String typesig = atts.getValue("attributeType");
if (typesig != null) {
type = EasikType.typeFromSignature(typesig);
} else {
String typename = atts.getValue("attributeTypeClass");
try {
type = EasikType.newType(typename, attributeMap(atts, "attributeType", "attributeTypeClass", "name"));
} catch (ClassNotFoundException e) {
System.err.println("Invalid type found in XML: '" + typename + "' (" + e.getMessage() + ")");
return;
}
}
EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> myAtt = new EntityAttribute<>(atts.getValue("name"), type, _newNode);
_curNodeAtts.put(atts.getValue("name"), myAtt);
_newNode.addEntityAttribute(myAtt);
} else if (qName.equals("uniqueKey")) {
// New EASIK has noderef, telling us what we refer to. In old easik,
// uniqueKey is under
// the node itself (but as a result, cannot contain edge
// references).
String noderef = atts.getValue("noderef");
if (noderef != null) {
// Restore _newNode and _curNodeAtts, since we're going to need
// them:
_newNode = _entityNodes.get(noderef);
_curNodeAtts = new LinkedHashMap<>();
for (EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> att : _newNode.getEntityAttributes()) {
_curNodeAtts.put(att.getName(), att);
}
}
_curUniqueKeyName = atts.getValue("name");
_curUniqueKeyElems = new LinkedList<>();
} else if (qName.equals("attref")) {
_curUniqueKeyElems.add(_curNodeAtts.get(atts.getValue("name")));
} else if (qName.equals("edgekeyref")) {
SketchEdge e = _edges.get(atts.getValue("id"));
if (e instanceof UniqueIndexable) {
_curUniqueKeyElems.add((UniqueIndexable) e);
} else {
System.err.println("Encountered an non-unique-indexable <edgekeyref> " + e);
}
} else if (qName.equals("edge")) {
SketchEdge newEdge;
String edgeType = atts.getValue("type");
// injective is an old EASIK attribute:
String injective = atts.getValue("injective");
if (injective != null) {
edgeType = atts.getValue("injective").equals("true") ? "injective" : "normal";
}
EntityNode source = _entityNodes.get(atts.getValue("source"));
EntityNode target = _entityNodes.get(atts.getValue("target"));
String id = atts.getValue("id");
String cascadeAtt = atts.getValue("cascade");
if (cascadeAtt == null) {
// This is from an export before Easik had per-edge cascading
// (in other words, before r583)
// We use the global preferences for cascading
String key = "sql_cascade", def = "restrict";
if (edgeType.equals("partial")) {
key = "sql_cascade_partial";
def = "set_null";
}
cascadeAtt = Easik.getInstance().getSettings().getProperty(key, def);
}
SketchEdge.Cascade cascade = cascadeAtt.equals("set_null") ? SketchEdge.Cascade.SET_NULL : cascadeAtt.equals("cascade") ? SketchEdge.Cascade.CASCADE : SketchEdge.Cascade.RESTRICT;
if (edgeType.equals("injective")) {
newEdge = new InjectiveEdge(source, target, id, cascade);
} else if (edgeType.equals("partial")) {
newEdge = new PartialEdge(source, target, id, cascade);
} else {
newEdge = new NormalEdge(source, target, id, cascade);
}
_edges.put(id, newEdge);
} else if (qName.equals("path")) {
_curPath = new LinkedList<>();
_curPathId = atts.getValue("id");
_curDomain = _entityNodes.get(atts.getValue("domain"));
} else if (qName.equals("edgeref")) {
_curPath.add(_edges.get(atts.getValue("id")));
} else if (// TRIANGLES
qName.equals("sumconstraint") || qName.equals("pullbackconstraint") || qName.equals("productconstraint") || qName.equals("commutativediagram") || qName.equals("equalizerconstraint") || qName.equals("limitconstraint")) // CF2012
{
_curConstraintX = Integer.parseInt(atts.getValue("x"));
_curConstraintY = Integer.parseInt(atts.getValue("y"));
_curConstraintVisible = atts.getValue("isVisible").equals("true");
_curConstraintPaths = new ArrayList<>();
_allConstraintsVisible = atts.getValue("isVisible").equals("true");
} else if (qName.equals("pathref")) {
// This is for compatibility with old versions of Easik (pre-2.0);
// new versions
// put <path> elements directly inside the various constraint
// elements.
_curConstraintPaths.add(_allPaths.get(atts.getValue("id")));
} else if (qName.equals("connectionParam")) {
_connParams.put(atts.getValue("name"), atts.getValue("value"));
} else if (qName.equals("synchronized")) {
// The existance of this tag tells us the sketch is synchronized
_curSketchSync = true;
}
}
Aggregations