use of easik.ui.SketchFrame 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.ui.SketchFrame 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.ui.SketchFrame 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.ui.SketchFrame in project fql by CategoricalData.
the class JDBCUpdateMonitor method updateRow.
/**
* Pops up a row entry dialog for the given table. The default field values
* will be the values stored in the row of the table who's primary ID
* matches the one given. Some cases call for use to restrict the update of
* foreign keys. Those cases are: a) A pullback b) The summands of a sum
* constrain c) The product of a product constraint If the table is in a
* constraint and the user wishes to break it the update is aborted leaving
* the old values in the record. Note: There are currently no checks to
* ensure that pk matches a record in our table.
*
* @param table
* The EntityNode representing the table we wish to update.
* @param pk
* The primary ID of the row whos data will be used to set
* defaults for our row entry dialog.
* @return The Success of the update.
*/
@Override
public boolean updateRow(final EntityNode table, final int pk) {
final DialogOptions dOpts = getDialogOptions(table);
try {
// Remove option to update foreign keys restricted by constraints
for (final ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> c : table.getConstraints()) {
for (final SketchEdge se : table.getOutgoingEdges()) {
if (c.hasEdge(se)) {
dOpts.fKeys.remove(cn.tableFK(se));
}
}
}
// Display dialog for user with defaults as old record values
final RowEntryDialog red = new RowEntryDialog(_theSketch.getFrame(), "Update " + table.getName() + ": " + cn.tablePK(table) + " = " + pk, dOpts.attToType, dOpts.fKeys, DatabaseUtil.getRecord(table, pk));
if (red.isAccepted()) {
final Set<ColumnEntry> input = new LinkedHashSet<>(red.getInput());
// if we do not have any new input, no need to execute an update
if (input.isEmpty()) {
return true;
}
final StringBuilder sb = new StringBuilder("UPDATE " + table.getName() + " SET ");
for (final ColumnEntry ce : input) {
sb.append(dbd.quoteId(ce.getColumnName())).append('=' + "?,");
}
// remove last comma
sb.delete(sb.length() - 1, sb.length());
sb.append(" WHERE ").append(cn.tablePK(table)).append('=').append(pk);
dbd.executePreparedUpdate(sb.toString(), input);
return true;
}
return false;
} catch (SQLException e) {
JOptionPane.showMessageDialog(table.getMModel().getFrame(), "Could not update record: " + e.getMessage());
return false;
}
}
use of easik.ui.SketchFrame 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