use of easik.database.types.EasikType in project fql by CategoricalData.
the class AttributeUI method getTabs.
/**
* Returns the tabs for the page; we separate the options into rough
* categories: numeric, string, date/time, and other (for boolean/custom).
*
* @return
*/
@Override
public List<OptionTab> getTabs() {
LinkedList<OptionTab> tabs = new LinkedList<>();
EasikType currentType = (_att != null) ? _att.getType() : null;
JPanel pInts = new JPanel(), pFloats = new JPanel(), pChars = new JPanel(), pTS = new JPanel(), pCustom = new JPanel();
pInts.setLayout(new BoxLayout(pInts, BoxLayout.Y_AXIS));
pFloats.setLayout(new BoxLayout(pFloats, BoxLayout.Y_AXIS));
pChars.setLayout(new BoxLayout(pChars, BoxLayout.Y_AXIS));
pTS.setLayout(new BoxLayout(pTS, BoxLayout.Y_AXIS));
pCustom.setLayout(new BoxLayout(pCustom, BoxLayout.Y_AXIS));
OptionTab numeric = new OptionTab("Numeric");
OptionTab text = new OptionTab("Character/data");
OptionTab datetime = new OptionTab("Date/time");
OptionTab other = new OptionTab("Other");
types = new ButtonGroup();
types.add(tInt = new JRadioButton("INTEGER"));
tInt.setToolTipText("An integer value field (usually a 32-bit int) that stores integer values from -2147483648 to 2147483647");
if (currentType instanceof Int) {
tInt.setSelected(true);
numeric.setInitial(true);
}
types.add(tSmallInt = new JRadioButton("SMALLINT"));
tSmallInt.setToolTipText("An integer value field (usually a 16-bit int) that stores integer values from (at least) -32768 to 32767");
if (currentType instanceof SmallInt) {
tSmallInt.setSelected(true);
numeric.setInitial(true);
}
types.add(tBigInt = new JRadioButton("BIGINT"));
tBigInt.setToolTipText("<html>An integer value field (usually a 64-bit int) that stores integer values from -9223372036854775808<br>to 9223372036854775807");
if (currentType instanceof BigInt) {
tBigInt.setSelected(true);
numeric.setInitial(true);
}
pInts.add(tInt);
pInts.add(tSmallInt);
pInts.add(tBigInt);
numeric.addOption(new Option("Integers", pInts));
types.add(tDouble = new JRadioButton("DOUBLE PRECISION"));
tDouble.setToolTipText("<html>A floating point value with at least 15 digits of precision (typically a standard 64-bit<br>floating-point value with 53 bits of precision).");
if (currentType instanceof DoublePrecision) {
tDouble.setSelected(true);
numeric.setInitial(true);
}
types.add(tFloat = new JRadioButton("FLOAT"));
tFloat.setToolTipText("<html>A floating point value with at least 6 digits of precision (typically a standard 32-bit<br>floating-point value with 24 bits of precision). This is sometimes known as a REAL, but a REAL is<br>also sometimes an alias for a DOUBLE PRECISION.");
if (currentType instanceof easik.database.types.Float) {
tFloat.setSelected(true);
numeric.setInitial(true);
}
pFloats.add(tDouble);
pFloats.add(tFloat);
numeric.addOption(new Option("Floating-point", pFloats));
types.add(tDecimal = new JRadioButton("NUMERIC"));
// We allow a max precision of 38, since that seems to be the lowest
// maximum (in MS SQL and Oracle)
// Pg supports up to 1000, and MySQL supports up to 63.
// *Any* default here doesn't make much sense; 10,2 is an arbitrary
// choice.
// This default allows anything from 0.00 to 99,999,999.99
int defPrec = 10, defScale = 2;
if (currentType instanceof Decimal) {
tDecimal.setSelected(true);
numeric.setInitial(true);
Decimal d = (Decimal) currentType;
defPrec = d.getPrecision();
defScale = d.getScale();
}
_decPrec = new JSpinner(new SpinnerNumberModel(defPrec, 1, 38, 1));
// The scale limits, for most databases, are 0 <= scale <= precision.
// Oracle, however
// permits the scale to be larger than the precision. We don't.
_decScale = new JSpinner(new SpinnerNumberModel(defScale, 0, 38, 1));
// Add a change listener to update the scale maximum to the current
// precision value:
_decPrec.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int scaleMax = ((SpinnerNumberModel) _decPrec.getModel()).getNumber().intValue();
((SpinnerNumberModel) _decScale.getModel()).setMaximum(scaleMax);
if (((SpinnerNumberModel) _decScale.getModel()).getNumber().intValue() > scaleMax) {
_decScale.setValue(new Integer(scaleMax));
}
}
});
JPanel decPanel = new JPanel();
decPanel.setLayout(new BoxLayout(decPanel, BoxLayout.X_AXIS));
decPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
decPanel.add(tDecimal);
decPanel.add(new JLabel("(Precision: "));
decPanel.add(JUtils.fixWidth(JUtils.fixHeight(_decPrec)));
decPanel.add(new JLabel(", Scale: "));
decPanel.add(JUtils.fixWidth(JUtils.fixHeight(_decScale)));
decPanel.add(new JLabel(")"));
decPanel.setToolTipText("<html>A fixed-point numeric type. Also known as DECIMAL.<br><br>This type is substantially slower than integer and floating-point types, but guarantees precision<br>for the range of values it supports. The \"precision\" value is the total number of digits storable, <br>and the \"scale\" is the number of digits stored after the decimal point. '12345.67' has precision 7<br>and scale 2.");
tDecimal.setToolTipText(decPanel.getToolTipText());
numeric.addOption(new Option("Fixed-point", decPanel));
types.add(tVarchar = new JRadioButton("VARCHAR"));
int vcs = 255;
if (currentType instanceof Varchar) {
tVarchar.setSelected(true);
text.setInitial(true);
vcs = ((Varchar) currentType).getSize();
}
_varcharSize = new JSpinner(new SpinnerNumberModel(vcs, 1, 255, 1));
JPanel vcPanel = new JPanel();
vcPanel.setLayout(new BoxLayout(vcPanel, BoxLayout.X_AXIS));
vcPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
vcPanel.add(tVarchar);
vcPanel.add(new JLabel("Size: "));
vcPanel.add(JUtils.fixHeight(JUtils.fixWidth(_varcharSize)));
vcPanel.setToolTipText("<html>Stores a string of characters of up to \"size\" characters. Unlike a CHAR, a VARCHAR column is<br>typically stored using the minimum storage space required, while a CHAR field pads shorter strings<br>to always store values of \"size\" length.");
tVarchar.setToolTipText(vcPanel.getToolTipText());
pChars.add(vcPanel);
types.add(tChar = new JRadioButton("CHAR"));
int cs = 255;
if (currentType instanceof Char) {
tChar.setSelected(true);
text.setInitial(true);
cs = ((Char) currentType).getSize();
}
_charSize = new JSpinner(new SpinnerNumberModel(cs, 1, 255, 1));
JPanel cPanel = new JPanel();
cPanel.setLayout(new BoxLayout(cPanel, BoxLayout.X_AXIS));
cPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
cPanel.add(tChar);
cPanel.add(new JLabel("Size: "));
cPanel.add(JUtils.fixHeight(JUtils.fixWidth(_charSize)));
cPanel.setToolTipText("<html>Stores a string of characters of up to \"size\" characters. Unlike a VARCHAR, a CHAR column is<br>typically padded up to the specified size to make it a fixed-width column (the padding is removed on<br>retrieval). Note that some databases implicitly convert CHAR columns to VARCHAR if other<br>variable-width columns exist in the table.");
tChar.setToolTipText(cPanel.getToolTipText());
pChars.add(cPanel);
text.addOption(new Option("Characters", pChars));
types.add(tText = new JRadioButton("TEXT (stores up to 4GB)"));
tText.setToolTipText("Stores large amounts of text data. Also known as a CLOB.");
if (currentType instanceof Text) {
tText.setSelected(true);
text.setInitial(true);
}
text.addOption(new Option("Text data", tText));
types.add(tBlob = new JRadioButton("BLOB (stores up to 4GB)"));
tBlob.setToolTipText("Stores large amounts of binary data (bytes). Will result in a BYTEA under PostgreSQL.");
if (currentType instanceof Blob) {
tBlob.setSelected(true);
text.setInitial(true);
}
text.addOption(new Option("Binary data", tBlob));
types.add(tDate = new JRadioButton("DATE"));
tDate.setToolTipText("A date field that does not include a time, such as '2008/07/14'");
if (currentType instanceof Date) {
tDate.setSelected(true);
datetime.setInitial(true);
}
datetime.addOption(new Option("Date only", tDate));
types.add(tTime = new JRadioButton("TIME"));
tTime.setToolTipText("A field that stores just a time (e.g. '12:13:14')");
if (currentType instanceof Time) {
tTime.setSelected(true);
datetime.setInitial(true);
}
datetime.addOption(new Option("Time only", tTime));
types.add(tTimestamp = new JRadioButton("TIMESTAMP (date and time)"));
tTimestamp.setToolTipText("<html>A field that stores a date and time (e.g. '2008/07/14 12:13:14'). Note that this is converted to a<br>DATETIME when using MySQL.");
if (currentType instanceof Timestamp) {
tTimestamp.setSelected(true);
datetime.setInitial(true);
}
pTS.add(tTimestamp);
datetime.addOption(new Option("Date & time", pTS));
types.add(tBoolean = new JRadioButton("BOOLEAN"));
tBoolean.setToolTipText("<html>A column that stores true/false values. Note that this type may be converted to a small integer<br>type by databases (such as MySQL) that do not fully support BOOLEAN data types");
if (currentType instanceof easik.database.types.Boolean) {
tBoolean.setSelected(true);
other.setInitial(true);
}
other.addOption(new Option("Boolean", tBoolean));
types.add(tCustom = new JRadioButton("Custom type:"));
if (currentType instanceof Custom) {
tCustom.setSelected(true);
other.setInitial(true);
_custom = JUtils.textField(((Custom) currentType).getCustom());
} else {
_custom = JUtils.textField("");
}
JPanel custPanel = new JPanel();
custPanel.setLayout(new BoxLayout(custPanel, BoxLayout.X_AXIS));
custPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
custPanel.setToolTipText("<html>Any SQL type supported by the SQL db that will be exported to can be entered here. No<br>verification of this field is performed: you must ensure that what you specify here is a valid type<br>for the SQL db type you will be using!");
tCustom.setToolTipText(custPanel.getToolTipText());
_custom.setToolTipText(custPanel.getToolTipText());
custPanel.add(tCustom);
custPanel.add(_custom);
other.addOption(new Option("Custom:", custPanel));
tabs.add(numeric);
tabs.add(text);
tabs.add(datetime);
tabs.add(other);
return tabs;
}
use of easik.database.types.EasikType in project fql by CategoricalData.
the class JDBCDriver method executePreparedUpdate.
/**
* Executes a given SQL updating statement. Which may be an INSERT, UPDATE,
* or DELETE statement. The statement must be in the form expected by
* java.sql.PreparedStatement
*
* @param sql
* The SQL statement to execute
* @param input
* The set of ColumnEntry objects from which our values are
* retrieved. Note: This works but relys on 'input' being
* iterated over in the same order that it was when 'sql' was
* generated.
*
* @throws SQLException
*/
public void executePreparedUpdate(final String sql, final Set<ColumnEntry> input) throws SQLException {
final PreparedStatement ps = prepareStatement(sql);
int col = 0;
for (final ColumnEntry entry : input) {
final EasikType type = entry.getType();
@SuppressWarnings("unused") final String value = entry.getValue();
col++;
// if value is NULL, assign and continue
if ("".equals(entry.getValue())) {
ps.setNull(col, type.getSqlType());
continue;
}
// bind appropriate type to the prepared statement
type.bindValue(ps, col, entry.getValue());
}
ps.execute();
}
use of easik.database.types.EasikType 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;
}
}
use of easik.database.types.EasikType in project fql by CategoricalData.
the class JDBCViewUpdateMonitor method getDialogOptions.
/**
* Gets the options needed for open a dialog for row insertion: map of
* attribute names to their type, and a map of foreign key names to a JTable
* of data they point to.
*
* @param table
* The node representing the table who's information we want
* @return Wrapper class holding the maps needed for insertion dialog
*/
private DialogOptions getDialogOptions(final EntityNode table) {
@SuppressWarnings("unused") final HashSet<ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>> constraints = new HashSet<ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>>(table.getConstraints());
final HashMap<String, EasikType> attToType = new HashMap<>(25);
final LinkedHashMap<String, EntityNode> fKeys = new LinkedHashMap<>(10);
// find attributes, and map to their EasikType
for (final EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> ea : table.getEntityAttributes()) {
attToType.put(ea.getName(), ea.getType());
}
// find all foreign keys, and add to foreign key set
for (final SketchEdge ske : table.getOutgoingEdges()) {
fKeys.put(cn.tableFK(ske), ske.getTargetEntity());
}
return new DialogOptions(attToType, fKeys);
}
Aggregations