use of easik.model.constraint.ProductConstraint 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.ProductConstraint in project fql by CategoricalData.
the class MySQLExporter method createConstraint.
/**
* @param constraint
* @param id
*
* @return
*/
@Override
public List<String> createConstraint(final ProductConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> constraint, final String id) {
final List<String> sql = new LinkedList<>();
final String delConName = "productConstraint" + id + "Delete";
StringBuilder proc = new StringBuilder(500);
proc.append("CREATE PROCEDURE ").append(quoteId(delConName)).append("(id ").append(pkType()).append(") BEGIN").append(lineSep);
EntityNode begin = null;
int j = 0;
// c.b_id = b.id JOIN d ON d.c_id = c.id...> WHERE <begin> = id;
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> p : constraint.getPaths()) {
if (begin == null) {
begin = p.getDomain();
}
proc.append(" DELETE ").append(quoteId(p.getCoDomain())).append(" FROM ").append(joinPath(p)).append(lineSep).append(" WHERE ").append(qualifiedPK(begin)).append(" = id;").append(lineSep);
// Federico Mora
StringBuilder proc1 = new StringBuilder(500);
StringBuilder body = new StringBuilder(50);
proc1.append("CREATE PROCEDURE ").append("Update" + constraint.getID() + "Proj" + j++).append("() BEGIN").append(lineSep);
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> q : constraint.getPaths()) {
if (p == q) {
// do nothing, cascade will take care of it
} else {
// making the update string which is used by all the delete
// procedures.
final LinkedList<SketchEdge> edges = q.getEdges();
if (edges.size() >= 2) {
Iterator<SketchEdge> iter = edges.iterator();
SketchEdge e = iter.next();
body.append(" UPDATE ").append(leftJoinPath(q)).append(lineSep);
body.append(" SET");
while (iter.hasNext()) {
SketchEdge ske = iter.next();
body.append(" " + quoteId(ske.getSourceEntity()) + ".BC" + constraint.getID() + " = " + false + ",");
}
body.delete(body.length() - 1, body.length());
body.append(" WHERE " + qualifiedFK(e) + " IS NULL;" + lineSep);
}
}
}
if (body.length() > 0) {
proc1.append(body);
proc1.append("END");
sql.add(proc1.toString());
// Now create the triggers to call the new procedure
addTrigger(p.getCoDomain(), "AFTER DELETE", "CALL " + quoteId("Update" + constraint.getID() + "Proj" + (j - 1)) + "()");
}
// end Federico Mora
}
// Select B.id From A Join B On A.f1 = B.id Join D On A.f3 = D.id Where
// D.id = 1
proc.append("END");
sql.add(proc.toString());
// Now create the trigger to call the new procedure
addTrigger(begin, "BEFORE DELETE", "CALL " + quoteId(delConName) + "(OLD." + quoteId(tablePK(begin)) + ')');
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> p : constraint.getPaths()) {
final EntityNode dest = p.getCoDomain();
final String conName = "productConstraint" + id + "Insert" + cleanId(dest);
final Collection<String> args = new LinkedList<>();
final Collection<String> params = new LinkedList<>();
args.add("id " + pkType());
params.add("NEW." + quoteId(tablePK(dest)));
// commented out by Sarah van der Laan -- caused error in generated
// SQL file (invalid foreign keys)
/**
* for (final SketchEdge shadow : dest.getShadowEdges()) {
* args.add(quoteId("NEW_shadow_" + tableFK(shadow)) + ' ' +
* pkType()); params.add("NEW." + quoteId(tableFK(shadow))); }
*/
proc = new StringBuilder(500);
proc.append("CREATE PROCEDURE ").append(quoteId(conName)).append('(').append(EasikTools.join(", ", args)).append(") BEGIN").append(lineSep).append(" DECLARE _lastId ").append(pkType()).append(';').append(lineSep);
final StringBuilder createIntermediates = new StringBuilder(250);
final Collection<String> clauses = new LinkedList<>();
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> q : constraint.getPaths()) {
if (p == q) {
continue;
}
// Older versions were doing "SELECT COUNT(*) FROM TABLE", but
// that has a big
// performance hit for very large, busy InnoDB tables, when all
// we really care
// about is non-empty:
clauses.add("(SELECT 1 FROM " + quoteId(q.getCoDomain()) + " LIMIT 1) = 1");
// If we end up putting anything in createIntermediate, we'll
// use these
// insertions when we insert the first row into one of the path
// targets
final LinkedList<SketchEdge> sketchEdgeLinkedList = q.getEdges();
final SketchEdge[] edges = sketchEdgeLinkedList.toArray(new SketchEdge[sketchEdgeLinkedList.size()]);
for (int i = edges.length - 1; i > 0; i--) {
final SketchEdge e = edges[i];
final EntityNode source = e.getSourceEntity();
final EntityNode target = e.getTargetEntity();
// after source there used to be dest.getShadowEdges();
createIntermediates.append(" ").append(insertInto(true, source, qualifiedPK(target), quoteId(target), Collections.singletonList(quoteId(tableFK(e))), null));
}
}
// In words: If the tables forming the domains of the other paths
// contain items.
proc.append(" IF ").append(EasikTools.join(" AND ", clauses)).append(" THEN").append(lineSep);
if (createIntermediates.length() > 0) {
// If we just inserted the first row, we're going to have to
// build a path of intermediate tables
// for the other paths, which we built in createIntermediate.
proc.append(" IF (SELECT COUNT(*) FROM (SELECT 1 FROM ").append(quoteId(dest)).append(" LIMIT 2) a) = 1 THEN").append(lineSep).append(createIntermediates).append(" END IF;").append(lineSep).append("").append(lineSep);
}
// Produce the intermediate path insertion strings
final LinkedList<SketchEdge> sketchEdgeLinkedList = p.getEdges();
final SketchEdge[] edges = sketchEdgeLinkedList.toArray(new SketchEdge[sketchEdgeLinkedList.size()]);
if (edges.length > 1) {
for (int i = edges.length - 1; i > 0; i--) {
final SketchEdge e = edges[i];
final EntityNode source = e.getSourceEntity();
@SuppressWarnings("unused") final EntityNode target = e.getTargetEntity();
// after source there used to be dest.getShadowEdges();
proc.append(" ").append(insertInto(true, source, null, null, Collections.singletonList(quoteId(tableFK(e))), Collections.singletonList((i == edges.length - 1) ? "id" : "LAST_INSERT_ID()")));
}
proc.append(" SET _lastId = LAST_INSERT_ID();").append(lineSep);
} else {
proc.append(" SET _lastId = id;").append(lineSep);
}
// Now the proper insertion
final List<String> columns = new LinkedList<>();
final Collection<String> values = new LinkedList<>();
final Collection<String> from = new LinkedList<>();
EntityNode thisTarget = null;
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> q : constraint.getPaths()) {
final EntityNode target = q.getFirstEdge().getTargetEntity();
columns.add(quoteId(tableFK(q.getFirstEdge())));
values.add(qualifiedPK(target));
from.add(quoteId(target));
if (q == p) {
thisTarget = target;
}
}
// after begin there used to be dest.getShadowEdges();
proc.append(" ").append(insertInto(true, begin, EasikTools.join(", ", values), EasikTools.join(" CROSS JOIN ", from) + " WHERE " + qualifiedPK(thisTarget) + " = _lastId", columns, null)).append(" END IF;").append(lineSep).append("END");
sql.add(proc.toString());
addTrigger(dest, "AFTER INSERT", "CALL " + quoteId(conName) + '(' + EasikTools.join(", ", params) + ')');
}
return delimit("$$", sql);
}
use of easik.model.constraint.ProductConstraint in project fql by CategoricalData.
the class XSDExporter method createConstraint.
/**
* Add an annotation explaining the product.
* <p/>
* Today, this is simply done by creating an annotation. For example in the
* standard product constraint in constraints.easik gives this annotation:
*
* <pre>
* <xs:annotation>
* <xs:documentation>
* ForAll.elem1 in (P1), ForAll.elem2 in (P2)
* Exists.p=(elem1,elem2) in Product
* </xs:documentation>
* </xs:annotation>
* </pre>
*
* @param prod
* the product diagram constraint.
*/
private void createConstraint(final ProductConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> prod) {
final List<ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> paths = prod.getPaths();
final EntityNode dom = paths.get(0).getDomain();
final XSDType domType = dom.getXsdType();
final List<String> elts = new ArrayList<>(paths.size());
int id = 0;
@SuppressWarnings("unused") 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) {
id++;
final LinkedList<SketchEdge> tmpPath = new LinkedList<>(path.getEdges());
tmpPath.removeFirst();
final String elem = "elem" + id;
elts.add(elem);
if (tmpPath.size() == 0) {
values.add("ForAll." + elem + " in (" + path.getCoDomain().getName() + ')');
} else {
values.add("ForAll." + elem + " in " + xmlJoinPath(tmpPath, true));
}
}
final String documentation = EasikTools.join(", ", values);
final String elements = "Exists.p=(" + EasikTools.join(",", elts) + ") in " + dom.getName();
domType.addAnnotation(new XSDAnnotation(documentation + lineSep + elements));
}
use of easik.model.constraint.ProductConstraint 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.ProductConstraint 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;
}
}
Aggregations