diff --git a/extra/jheidi/ajl b/extra/jheidi/ajl
new file mode 100755
index 00000000..a74d3fea
--- /dev/null
+++ b/extra/jheidi/ajl
@@ -0,0 +1 @@
+java -cp .:classes:lib/ajl.jar:$JAVA_HOME/lib/tools.jar:lib/editor.jar:lib/mysql-connector-java-5.0.7-bin.jar:lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript $1.ajl $2 $3 $4 $5 $6 $7 $8 $9
diff --git a/extra/jheidi/ajl-leopard b/extra/jheidi/ajl-leopard
new file mode 100644
index 00000000..54e0fb44
--- /dev/null
+++ b/extra/jheidi/ajl-leopard
@@ -0,0 +1 @@
+java -Dapple.laf.useScreenMenuBar=true -Djava.library.path=lib -Dlf.isLeopard=true -cp .:classes:lib/ajl.jar:$JAVA_HOME/lib/tools.jar:lib/editor.jar:lib/mysql-connector-java-5.0.7-bin.jar:lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript $1.ajl $2 $3 $4 $5 $6 $7 $8 $9
diff --git a/extra/jheidi/ajl-tiger b/extra/jheidi/ajl-tiger
new file mode 100644
index 00000000..ab193a2c
--- /dev/null
+++ b/extra/jheidi/ajl-tiger
@@ -0,0 +1 @@
+java -Dapple.laf.useScreenMenuBar=true -Djava.library.path=lib -Dlf.isTiger=true -cp .:classes:lib/ajl.jar:$JAVA_HOME/lib/tools.jar:lib/editor.jar:lib/mysql-connector-java-5.0.7-bin.jar:lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript $1.ajl $2 $3 $4 $5 $6 $7 $8 $9
diff --git a/extra/jheidi/ajl.cmd b/extra/jheidi/ajl.cmd
new file mode 100755
index 00000000..864a49ef
--- /dev/null
+++ b/extra/jheidi/ajl.cmd
@@ -0,0 +1,2 @@
+java -cp .;classes;lib/ajl.jar;%JAVA_HOME%/lib/tools.jar;lib/editor.jar;lib/mysql-connector-java-5.0.7-bin.jar;lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript %1.ajl %2 %3 % 4 %5 %6 %7 %8 %9
+
diff --git a/extra/jheidi/bin/jheidi b/extra/jheidi/bin/jheidi
new file mode 100755
index 00000000..89ec6536
--- /dev/null
+++ b/extra/jheidi/bin/jheidi
@@ -0,0 +1,3 @@
+#bin/sh
+
+java -DusePrecompiledClassFiles=true -cp jheidi.jar:lib/ajl.jar:lib/editor.jar:lib/mysql-connector-java-5.0.7-bin.jar:lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript jheidi
diff --git a/extra/jheidi/bin/jheidi-leopard b/extra/jheidi/bin/jheidi-leopard
new file mode 100755
index 00000000..33e6857d
--- /dev/null
+++ b/extra/jheidi/bin/jheidi-leopard
@@ -0,0 +1,3 @@
+#bin/sh
+
+java -Dapple.laf.useScreenMenuBar=true -Djava.library.path=lib -Dlf.isLeopard=true -Xdock:name="JHeidi" -DusePrecompiledClassFiles=true -cp lib/quaqua.jar:jheidi.jar:lib/ajl.jar:lib/editor.jar:lib/mysql-connector-java-5.0.7-bin.jar:lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript jheidi
diff --git a/extra/jheidi/bin/jheidi-tiger b/extra/jheidi/bin/jheidi-tiger
new file mode 100755
index 00000000..39447203
--- /dev/null
+++ b/extra/jheidi/bin/jheidi-tiger
@@ -0,0 +1,3 @@
+#bin/sh
+
+java -Dapple.laf.useScreenMenuBar=true -Dlf.isTiger=true -Xdock:name="JHeidi" -DusePrecompiledClassFiles=true -cp jheidi.jar:lib/ajl.jar:lib/editor.jar:lib/mysql-connector-java-5.0.7-bin.jar:lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript jheidi
diff --git a/extra/jheidi/bin/jheidi.ajl b/extra/jheidi/bin/jheidi.ajl
new file mode 100644
index 00000000..06641c7c
--- /dev/null
+++ b/extra/jheidi/bin/jheidi.ajl
@@ -0,0 +1,127 @@
+ import java.util.*;
+ import javax.swing.*;
+
+ Frame app = new Frame("connectDialog", "Connection To MySQL");
+ WindowContext context = app.getWindowContext();
+
+ app.events("connectDialogEvents");
+ app.tabLayout();
+ app.insets(10, 12);
+ app.image("logo", "images/mysql-logo.gif")
+ .space(LF.isLeopard?2:5)
+ .vspace(-1)
+ .button("New", 110)
+ .setTab()
+ .space(20)
+ .button("Save", 110)
+ .space(20)
+ .button("Delete", 110)
+ .nextRow()
+ .vspace(10)
+ .tab(1)
+ .space(4)
+ .text("Description:", 92).setTab()
+ .space(0)
+ .combo("connProfiles", new String[] {"New Connection"}, 200).setTab() /* again wtf is this happening is the baseline aligned or what? */
+ .button("Rename", 74) /* what the fuck is wrong with this dropdown? */
+ .nextRow()
+ .tab(2)
+ .text("Hostname/IP:")
+ .tab(3)
+ .field("host", 281)
+ .nextRow()
+ .tab(2)
+ .text("User:")
+ .tab(3)
+ .field("user", 281)
+ .nextRow()
+ .tab(2)
+ .text("Password:")
+ .tab(3)
+ .password("password", 281)
+ .nextRow()
+ .tab(2)
+ .text("Port:")
+ .tab(3)
+ .field("port", 50)
+ .space(10)
+ .text("Timeout:")
+ .space(5)
+ .field("timeout", 50)
+ .space(2)
+ .text("seconds")
+ .nextRow()
+ .tab(3)
+ .vspace(2)
+ .checkbox("compress", "Use compressed protocol", false)
+ .nextRow()
+ .tab(2)
+ .text("Database(s):
(separated by
semicolon)")
+ .tab(3)
+ .field("dbs", 281)
+ .nextRow()
+ .tab(3)
+ .checkbox("sort", "Sort databases A-Z", true)
+ .nextRow()
+ .vspace(10)
+ .line(513)
+ .nextRow()
+ .tab(1)
+ .vspace(7)
+ .button("Save/Connect", LF.isMac?112: 110)
+ .space(20)
+ .button("Connect", 110)
+ .space(20)
+ .button("Cancel", 110)
+ .setDefaultButton("Save/Connect");
+
+
+ Combo connProfiles = context.get("/connProfiles");
+ connProfiles.requestFocus();
+ HashObject profiles = new HashObject();
+ connProfiles.setProperty("profiles", profiles);
+ String[] names = null;
+
+ try
+ {
+ List connections = (List)FileUtil.toList(".connectionProfiles");
+ log.debug("connection profiles exist: " + connections.size());
+ names = new String[connections.size()];
+ int count = 0;
+ for (String profileString : connections )
+ {
+ String[] profileAttrs = profileString.split(":");
+ HashObject profile = new HashObject();
+ for (String attr : profileAttrs )
+ {
+ String[] keyValue = attr.split("=");
+ String value = "";
+ if ( keyValue.length == 2 )
+ {
+ value = keyValue[1];
+ }
+ if ( "name".equals(keyValue[0]) )
+ {
+ names[count] = value;
+ }
+ profile.put(keyValue[0], value);
+ }
+ if ( names[count] != null )
+ {
+ profiles.put(names[count++], profile);
+ }
+ }
+
+ }
+ catch (Exception e) { e.printStackTrace();/*no profiles i guess*/ }
+
+ if ( profiles.size() > 0 )
+ {
+ connProfiles.setModel(new DefaultComboBoxModel(names));
+ connProfiles.select(names[0]);
+ }
+
+ app.visible();
+
+
+
diff --git a/extra/jheidi/bin/jheidi.cmd b/extra/jheidi/bin/jheidi.cmd
new file mode 100755
index 00000000..c23ca338
--- /dev/null
+++ b/extra/jheidi/bin/jheidi.cmd
@@ -0,0 +1,3 @@
+@echo off
+
+java -DusePrecompiledClassFiles=true -cp jheidi.jar;lib/ajl.jar;lib/editor.jar;lib/mysql-connector-java-5.0.7-bin.jar;lib/log4j-1.2.13.jar -Dlog4jconfig=logs/log4jconfig.xml com.rendion.ajl.AjlScript jheidi
diff --git a/extra/jheidi/bin/jheidi.exe b/extra/jheidi/bin/jheidi.exe
new file mode 100755
index 00000000..79ba0d42
Binary files /dev/null and b/extra/jheidi/bin/jheidi.exe differ
diff --git a/extra/jheidi/build/jheidi-alpha-bin.zip b/extra/jheidi/build/jheidi-alpha-bin.zip
new file mode 100644
index 00000000..a21299b3
Binary files /dev/null and b/extra/jheidi/build/jheidi-alpha-bin.zip differ
diff --git a/extra/jheidi/build/jheidi-alpha-src.zip b/extra/jheidi/build/jheidi-alpha-src.zip
new file mode 100644
index 00000000..d6966f03
Binary files /dev/null and b/extra/jheidi/build/jheidi-alpha-src.zip differ
diff --git a/extra/jheidi/connectDialogEvents.ajl b/extra/jheidi/connectDialogEvents.ajl
new file mode 100644
index 00000000..ed7dee87
--- /dev/null
+++ b/extra/jheidi/connectDialogEvents.ajl
@@ -0,0 +1,164 @@
+import javax.swing.*;
+import java.util.*;
+
+String who = arg("source");
+
+log.debug("event received: " + who);
+WindowContext context = argObj("windowContext");
+Frame dialog = context.get("/");
+
+Combo connProfiles = context.get("/connProfiles");
+HashObject profiles = connProfiles.getProperty("profiles");
+
+
+if ( "Delete".equals(who) )
+{
+ if ( dialog.popupConfirm("Confirm Delete!", "Are you sure you want to delete this profile?") )
+ {
+ String profileToDelete = connProfiles.getText();
+ connProfiles.setProperty("lastProfile", null);
+ ((DefaultComboBoxModel)connProfiles.getModel()).removeElement( profileToDelete );
+ profiles.remove(profiles.getObject(profileToDelete));
+ profiles.keySet().remove(profileToDelete);
+
+ }
+
+}
+else if ("Rename".equals(who) )
+{
+ String newName = dialog.popupQuestion("Rename Connection", "Enter a new name for the connection profile:");
+ if ( newName != null )
+ {
+ DefaultComboBoxModel model = (DefaultComboBoxModel)connProfiles.getModel();
+ newName = newName.trim();
+
+ for (int i=0; i < model.getSize(); i++)
+ {
+ if (newName.equalsIgnoreCase((String)model.getElementAt(i)))
+ {
+ dialog.popupMessage("Cant Create!", "A profile with that name already exists!");
+ return;
+ }
+ }
+
+ String profileToRename = connProfiles.getText();
+ HashObject profile = (HashObject)profiles.getObject(profileToRename);
+ profile.put("name", newName);
+ profiles.remove(profiles.getObject(profileToRename));
+ profiles.keySet().remove(profileToRename);
+ profiles.put(newName, profile);
+ connProfiles.setProperty("lastProfile", newName );
+ int pos = model.getIndexOf(profileToRename);
+ model.insertElementAt(newName, pos);
+ model.removeElementAt(pos+1);
+
+ }
+}
+else if ("New".equals(who) )
+{
+ String newName = dialog.popupQuestion("New Connection", "Enter a name for the new connection profile:");
+ if ( newName != null )
+ {
+
+ DefaultComboBoxModel model = (DefaultComboBoxModel)connProfiles.getModel();
+ newName = newName.trim();
+
+ for (int i=0; i < model.getSize(); i++)
+ {
+ if (newName.equalsIgnoreCase((String)model.getElementAt(i)))
+ {
+ dialog.popupMessage("Cant Create!", "A profile with that name already exists!");
+ return;
+ }
+ }
+
+ HashObject profile = ((HashObject)profiles.getObject("Default Local")).copy();
+ profile.put("name", newName);
+ profiles.put(newName, profile);
+ model.addElement(newName);
+ model.setSelectedItem(newName);
+
+ }
+
+}
+else if ("Save".equals(who) || "Save/Connect".equals(who) || "Connect".equals(who))
+{
+ args().put("stateCmd", "flush");
+ args().put("profileKey", connProfiles.getText());
+ script("connectDialogState", args());
+
+ if ( who.startsWith("Save") )
+ {
+ StringBuilder buffer = new StringBuilder(1000);
+ for (HashObject h : (List) profiles)
+ {
+ buffer.append("name=").append(h.get("name")).append(":");
+ buffer.append("host=").append(h.get("host")).append(":");
+ buffer.append("user=").append(h.get("user")).append(":");
+ buffer.append("password=").append(h.get("password")).append(":");
+ buffer.append("port=").append(h.get("port")).append(":");
+ buffer.append("timeout=").append(h.get("timeout")).append(":");
+ buffer.append("compress=").append(h.get("compress")).append(":");
+ buffer.append("sort=").append(h.get("sort")).append(":");
+ buffer.append("dbs=").append(h.get("dbs")).append("\n");
+ }
+
+ FileUtil.fromString(".connectionProfiles", buffer.toString());
+ }
+
+ if ( who.endsWith("Connect"))
+ {
+ HashObject profile = (HashObject)profiles.getObject(connProfiles.getText());
+
+ args().put("profile", profile);
+ DB db = (DB)script("testConnect", args());
+ if (db != null)
+ {
+ dialog.dispose();
+ script("showMainWindow", args());
+ }
+ }
+
+}
+else if ("connProfiles".equals(who))
+{
+ String lastProfileKey = connProfiles.getProperty("lastProfile");
+
+ if ( !connProfiles.getText().equals(lastProfileKey) )
+ {
+ if ( lastProfileKey != null && profiles.getObject(lastProfileKey) != null )
+ {
+ args().put("stateCmd", "flush");
+ args().put("profileKey", lastProfileKey);
+ script("connectDialogState", args());
+ }
+
+ HashObject profile = (HashObject) profiles.getObject(connProfiles.getText());
+
+ ((Field)context.get("/host")).setText(profile.get("host"));
+ ((Field)context.get("/user")).setText(profile.get("user"));
+ ((Password)context.get("/password")).setText(profile.get("password"));
+ ((Field)context.get("/port")).setText(profile.get("port"));
+ ((Field)context.get("/timeout")).setText(profile.get("timeout"));
+ ((Field)context.get("/port")).setText(profile.get("port"));
+ ((Field)context.get("/dbs")).setText(profile.get("dbs"));
+
+ boolean compress = "true".equals(profile.get("compress"));
+ ((CheckBox)context.get("/compress")).setSelected(compress);
+ boolean sort = "true".equals(profile.get("sort"));
+ ((CheckBox)context.get("/sort")).setSelected(sort);
+
+ boolean enabled = !"Default Local".equals(connProfiles.getText());
+ ((Button)context.get("/Delete")).setEnabled(enabled);
+ ((Button)context.get("/Rename")).setEnabled(enabled);
+
+ connProfiles.setProperty("lastProfile", connProfiles.getText());
+ }
+
+}
+else if ("Cancel".equals(who) )
+{
+ dialog.disposeOrExit(0);
+}
+
+
diff --git a/extra/jheidi/connectDialogState.ajl b/extra/jheidi/connectDialogState.ajl
new file mode 100644
index 00000000..d3bad671
--- /dev/null
+++ b/extra/jheidi/connectDialogState.ajl
@@ -0,0 +1,38 @@
+
+String stateCmd = arg("stateCmd");
+
+log.debug("stateCmd:" + stateCmd);
+WindowContext context = argObj("windowContext");
+
+if ("flush".equals(stateCmd))
+{
+ String profileKey = arg("profileKey");
+ Combo connProfiles = context.get("/connProfiles");
+ HashObject profiles = connProfiles.getProperty("profiles");
+
+ HashObject profile = (HashObject) profiles.getObject(profileKey);
+ String value = ((Field)context.get("/host")).getText();
+ profile.put("host", value == null ? "" : value.trim() );
+ value = ((Field)context.get("/user")).getText();
+ profile.put("user", value == null ? "" : value.trim() );
+ value = ((Password)context.get("/password")).getText();
+ profile.put("password", value == null ? "" : value.trim() );
+ value = ((Field)context.get("/port")).getText();
+ profile.put("port", value == null ? "" : value.trim() );
+ value = ((Field)context.get("/timeout")).getText();
+ profile.put("timeout", value == null ? "" : value.trim() );
+ value = ((Field)context.get("/dbs")).getText();
+ profile.put("dbs", value == null ? "" : value.trim() );
+ boolean checked = ((CheckBox)context.get("/compress")).isSelected();
+ profile.put("compress", checked ? "true" : "false");
+ checked = ((CheckBox)context.get("/sort")).isSelected();
+ profile.put("sort", checked ? "true" : "false");
+
+ return profile;
+
+
+}
+
+
+
+
diff --git a/extra/jheidi/createDBDialog.ajl b/extra/jheidi/createDBDialog.ajl
new file mode 100644
index 00000000..e9e25d84
--- /dev/null
+++ b/extra/jheidi/createDBDialog.ajl
@@ -0,0 +1,46 @@
+
+ WindowContext parentContext = argObj("windowContext");
+
+ Dialog dlg = new Dialog((Frame)parentContext.get("/"), "createDBDialog", "Create Database");
+ WindowContext context = dlg.getWindowContext();
+ context.put("db", parentContext.get("db"));
+
+ dlg.events("createDBEvents");
+ dlg.tabLayout();
+ dlg.insets(10, 10);
+ dlg.text("Name:", 90)
+ .setTab()
+ .space(10)
+ .field("dbName", 200)
+ .setTab()
+ .nextRow()
+ .tab(1)
+ .text("Character Set:")
+ .tab(2)
+ .combo("charSets", new String[] {"Hi", "There"}, 200)
+ .nextRow()
+ .tab(1)
+ .text("Collation:")
+ .tab(2)
+ .combo("collations", new String[] {"hi"}, 200)
+ .nextRow()
+ .vspace(10)
+ .space(42)
+ .button("Ok", 110)
+ .space(10)
+ .button("Cancel", 110);
+
+ dlg.setDefaultButton((Button)context.get("/Ok"));
+
+ DB db = context.get("db");
+ DB.Result result = db.execute("show character set");
+
+ Combo combo = context.get("/charSets");
+ ComboUtils.populate(combo, result, 0);
+ combo.select("latin1");
+
+ dlg.visible();
+
+ return context.get("dlgResult");
+
+
diff --git a/extra/jheidi/createDBEvents.ajl b/extra/jheidi/createDBEvents.ajl
new file mode 100644
index 00000000..9cee00da
--- /dev/null
+++ b/extra/jheidi/createDBEvents.ajl
@@ -0,0 +1,50 @@
+
+ String who = arg("source");
+
+ WindowContext context = argObj("windowContext");
+ log.debug("event received: " + who);
+
+ if ( "Ok".equals(who) )
+ {
+ Dialog d = context.get("/");
+ Field dbName = context.get("/dbName");
+ Combo charSet = context.get("/charSets");
+ Combo coll = context.get("/collations");
+
+ DB db = context.get("db");
+ db.execute("create database " + dbName.getText() + " default character set '"
+ + charSet.getText() + "' default collate '" + coll.getText() + "'");
+
+ context.put("dlgResult", Boolean.TRUE);
+
+ d.dispose();
+
+ } else if ( "Cancel".equals(who) )
+ {
+ Dialog d = context.get("/");
+ d.dispose();
+ }
+ else if ("charSets".equals(who))
+ {
+ DB db = context.get("db");
+ DB.Result result = db.execute("show collation where charset='" + ((Combo)context.get("/charSets")).getText() + "'");
+
+ String def = null;
+
+ for (HashObject ho: result)
+ {
+ if ("Yes".equalsIgnoreCase((String)ho.get(3)))
+ {
+ def = (String) ho.get(0);
+ break;
+ }
+ }
+
+ Combo combo = context.get("/collations");
+ ComboUtils.populate(combo, result, 0);
+ combo.select(def);
+
+ }
+
+
+
diff --git a/extra/jheidi/createTableDialog.ajl b/extra/jheidi/createTableDialog.ajl
new file mode 100755
index 00000000..04daa724
--- /dev/null
+++ b/extra/jheidi/createTableDialog.ajl
@@ -0,0 +1,183 @@
+ import java.awt.Dimension;
+ import java.awt.Component;
+ import javax.swing.*;
+
+ WindowContext parentContext = argObj("windowContext");
+
+ Dialog dlg = new Dialog((Frame)parentContext.get("/"), "createTableDialog", "Create Table");
+ WindowContext context = dlg.getWindowContext();
+ context.put("db", parentContext.get("db"));
+
+ dlg.events("createTableEvents");
+ dlg.tabLayout();
+ dlg.insets(10, 10);
+ dlg.text("Name:", 73)
+ .setTab()
+ .field("tableName", 200)
+ .setTab()
+ .space(5)
+ .text("Engine:", 96)
+ .setTab()
+ .combo("engines", new String[] {"engines"}, 200)
+ .setTab()
+ .nextRow()
+ .tab(1)
+ .text("Database:")
+ .tab(2)
+ .combo("databases", new String[] {"databases", "There"}, 200)
+ .tab(3)
+ .text("Character set:")
+ .tab(4)
+ .combo("charSets", new String[] { "hi"}, 200)
+ .nextRow()
+ .tab(1)
+ .text("Comment:")
+ .tab(2)
+ .field("comment", 200)
+ .tab(3)
+ .text("Collation:")
+ .tab(4)
+ .combo("collations", new String[] {"hi"}, 200)
+ .nextRow()
+ .vspace(5)
+ .line(595)
+ .nextRow()
+ .tab(1)
+ .text("Columns:")
+ .nextRow()
+ .tab(1)
+ .field("fieldName", 180)
+ .baseline()
+ .space(5)
+ .button("Add", 75)
+ .setTab()
+ .space(16)
+ .vspace(-10)
+ .groupbox("Column Properties",307,230)
+ .nextRow()
+ .vspace(3)
+ .tab(1)
+ .listbox("fields", new String[] {}, 180, 186)
+ .tab(5)
+ .button("Rename", 75)
+ .space(38)
+ .vspace(-13)
+ .text("Type:", 88)
+ .setTab()
+ .combo("types", new String[] {"VARCHAR"}, 170)
+ .setTab()
+ .nextRow()
+ .tab(6)
+ .text("Length/Set:")
+ .tab(7)
+ .field("lengthSet", 170)
+ .nextRow()
+ .tab(6)
+ .text("Default:")
+ .tab(7)
+ .field("defaultValue", 170)
+ .nextRow()
+ .vspace(LF.isWin?20:10)
+ .tab(6)
+ .space(LF.isWin?5:0)
+ .checkbox("primary", "Primary", 90, false)
+ .setTab()
+ .checkbox("index", "Index", 88, false)
+ .setTab()
+ .checkbox("unique", "Unique", 70, false)
+ .setTab()
+ .nextRow()
+ .tab(8)
+ .checkbox("notNull", "Not Null", false)
+ .tab(9)
+ .checkbox("autoInc", "Auto Increment", false)
+ .nextRow()
+ .tab(8)
+ .checkbox("binary", "Binary", false)
+ .tab(9)
+ .checkbox("unsigned", "Unsigned", false)
+ .tab(10)
+ .checkbox("zeroFill", "Zero Fill",80, false)
+ .nextRow();
+
+ dlg.baseline((Component)context.get("/Rename"));
+
+ dlg.tab(5)
+ .vspace(1)
+ .button("Remove", 75)
+ .nextRow()
+ .vspace(1)
+ .tab(5)
+ .imageButton("Up", "images/up.gif", 75)
+ .nextRow()
+ .tab(5)
+ .vspace(1)
+ .imageButton("Down", "images/down.gif", 75)
+ .nextRow();
+
+ dlg.baseline((Component)context.get("/fieldsScrollPane"));
+
+ dlg.vspace(193)
+ .line(595)
+ .nextRow()
+ .vspace(5)
+ .space(364)
+ .button("Create", 110)
+ .space(5)
+ .button("Cancel", 110);
+
+ Text lbl = context.get("/gbColumn Properties");
+ JScrollPane listBox = context.get("/fieldsScrollPane");
+ Field field = context.get("/fieldName");
+
+ lbl.setPreferredSize(new Dimension(lbl.getPreferredSize().width, listBox.getPreferredSize().height + field.getPreferredSize().height + 21));
+
+ //because of this side by side layout we cant use default taborder :(
+ String[] tabs = new String [] { "/tableName", "/databases", "/comment", "/engines", "/charSets", "/collations",
+ "/fieldName", "/fields", "/Add", "/Rename", "/Remove", "/Up", "/Down", "/types", "/lengthSet", "/defaultValue",
+ "/primary", "/index", "/unique", "/notNull", "/autoInc", "/binary", "/unsigned", "/zeroFill", "/Create", "/Cancel" };
+
+ new TabOrder(dlg, tabs);
+
+ ((Field)context.get("/tableName")).setText("TableName");
+ ((ListBox)context.get("/fields")).events("fieldListEvents");
+
+ DB db = context.get("db");
+ db.begin();
+ DB.Result result = db.execute("show character set");
+ DB.Result dbs = db.execute("show databases");
+ DB.Result engines = db.execute("show engines");
+ db.end();
+
+ Combo combo = context.get("/charSets");
+ ComboUtils.populate(combo, result, 0);
+ combo.select("latin1");
+
+ combo = context.get("/databases");
+ ComboUtils.populate(combo, dbs, 0);
+ if ( parentContext.get("currentDB") != null )
+ {
+ combo.select((String)parentContext.get("currentDB"));
+ }
+
+ combo = context.get("/engines");
+ ComboUtils.populate(combo, engines, 0);
+ for (int i=0; i < engines.size(); i++)
+ {
+ HashObject engine = engines.get(i);
+ if ( "DEFAULT".equals(engine.get("support")))
+ {
+ combo.select(engine.get(0));
+ break;
+ }
+ }
+
+ HashObject newArgs = new HashObject();
+ newArgs.put("windowContext", context);
+ script("initMySQLTypes", newArgs);
+
+ dlg.visible();
+
+ return context.get("dlgResult");
+
+
diff --git a/extra/jheidi/createTableEvents.ajl b/extra/jheidi/createTableEvents.ajl
new file mode 100644
index 00000000..4b89c3c8
--- /dev/null
+++ b/extra/jheidi/createTableEvents.ajl
@@ -0,0 +1,242 @@
+ import javax.swing.*;
+ import java.util.*;
+
+ String who = arg("source");
+ WindowContext context = argObj("windowContext");
+
+ log.debug("event received: " + who);
+
+ if ( "Create".equals(who) )
+ {
+ Dialog d = context.get("/");
+ ListBox l = context.get("/fields");
+ ListDataModel model = (ListDataModel)l.getModel();
+ StringBuilder buffer = new StringBuilder(3000);
+
+ String tableName = ((Field)context.get("/tableName")).getText();
+ String dbName = ((Combo)context.get("/databases")).getText();
+ String comment = ((Field)context.get("/comment")).getText();
+ String engine = ((Combo)context.get("/engines")).getText();
+ String charSet = ((Combo)context.get("/charSets")).getText();
+ String coll = ((Combo)context.get("/collations")).getText();
+
+ if ( tableName == null || tableName.trim().length() == 0 )
+ {
+ d.popupMessage("Create Table", "Please provide a table name before saving.");
+ return;
+ } else if ( dbName == null )
+ {
+ d.popupMessage("Create Table", "Please select a database for the new table before saving.");
+ return;
+ } else if ( model.size() == 0 )
+ {
+ d.popupMessage("Create Table", "Please add at least one field before saving.");
+ return;
+ }
+
+ args().put("fieldKey", l.getSelectedValue());
+ script("createTableState", args());
+
+ buffer.append("create table ").append(dbName).append(".").append(tableName).append(" (");
+
+ List priKeys = new ArrayList();
+ List uniques = new ArrayList();
+ List indxs = new ArrayList();
+
+ for (int i=0; i < model.size(); i++)
+ {
+ String fieldName = (String)model.get(i);
+ HashObject def = l.getProperty(fieldName);
+ if ( def != null )
+ {
+ buffer.append(fieldName).append(" ").append(def.get("type"));
+ if ( def.get("length") != null && def.get("length").trim().length() > 0)
+ {
+ buffer.append("(").append(def.get("length")).append(")");
+ }
+ if ( ((Boolean)def.getObject("binary")) == Boolean.TRUE )
+ buffer.append(" binary");
+ if ( ((Boolean)def.getObject("unsigned")) == Boolean.TRUE )
+ buffer.append(" unsigned");
+ if ( ((Boolean)def.getObject("zeroFill")) == Boolean.TRUE )
+ buffer.append(" zerofill");
+
+ if ( def.get("default") != null && def.get("default").trim().length() > 0)
+ {
+ buffer.append(" default '").append(def.get("default")).append("'");
+ }
+
+ if ( ((Boolean)def.getObject("notNull")) == Boolean.TRUE )
+ buffer.append(" not null");
+ if ( ((Boolean)def.getObject("autoInc")) == Boolean.TRUE )
+ buffer.append(" auto_increment");
+
+ if (i != model.size()-1)
+ {
+ buffer.append(", ");
+ }
+
+ if ( ((Boolean)def.getObject("primary")) == Boolean.TRUE )
+ priKeys.add(fieldName);
+
+ if ( ((Boolean)def.getObject("unique")) == Boolean.TRUE )
+ uniques.add(fieldName);
+
+ if ( ((Boolean)def.getObject("index")) == Boolean.TRUE )
+ indxs.add(fieldName);
+ }
+ }
+
+ if ( priKeys.size() > 0)
+ {
+ buffer.append(", PRIMARY KEY(");
+
+ for ( int i=0; i < priKeys.size(); i++)
+ {
+ buffer.append(priKeys.get(i));
+ buffer.append(i!=priKeys.size()-1?",":"");
+ }
+ buffer.append(")");
+ }
+
+ if ( uniques.size() > 0)
+ {
+ buffer.append(", UNIQUE(");
+
+ for ( int i=0; i < uniques.size(); i++)
+ {
+ buffer.append(uniques.get(i));
+ buffer.append(i!=uniques.size()-1?",":"");
+ }
+ buffer.append(")");
+ }
+
+ if ( indxs.size() > 0)
+ {
+ buffer.append(", INDEX(");
+
+ for ( int i=0; i < indxs.size(); i++)
+ {
+ buffer.append(indxs.get(i));
+ buffer.append(i!=indxs.size()-1?",":"");
+ }
+ buffer.append(")");
+ }
+ buffer.append(")");
+
+ buffer.append(" type=").append(engine)
+ .append(" default charset ").append(charSet)
+ .append(" collate ").append(coll);
+
+ // CREATE TABLE `test`.`TableName` (`bob` TINYINT (10) UNSIGNED ZEROFILL DEFAULT 'goo' NOT NULL AUTO_INCREMENT, PRIMARY KEY(`bob`), UNIQUE(`bob`), INDEX(`bob`)) TYPE = InnoDB /*!40100 DEFAULT CHARSET latin1 COLLATE latin1_swedish_ci */
+ log.debug("heres the statement: " + buffer.toString());
+
+ DB db = context.get("db");
+ db.execute(buffer.toString());
+
+ context.put("dlgResult", Boolean.TRUE);
+
+ d.dispose();
+
+ } else if ( "Cancel".equals(who) )
+ {
+ Dialog d = context.get("/");
+ d.dispose();
+ }
+ else if ("charSets".equals(who))
+ {
+ DB db = context.get("db");
+ DB.Result result = db.execute("show collation where charset='" + ((Combo)context.get("/charSets")).getText() + "'");
+
+ String def = null;
+
+ for (HashObject ho: result)
+ {
+ if ("Yes".equalsIgnoreCase((String)ho.get(3)))
+ {
+ def = (String)ho.get(0);
+ break;
+ }
+ }
+
+ Combo combo = context.get("/collations");
+ ComboUtils.populate(combo, result, 0);
+ combo.select(def);
+
+ }
+ else if ("Add".equals(who) )
+ {
+ Field f = context.get("/fieldName");
+ ListBox l = context.get("/fields");
+ ListDataModel model = (ListDataModel)l.getModel();
+ String fieldName = f.getText();
+
+ if ( fieldName != null && (fieldName.trim().length() > 0) &&
+ !model.contains(fieldName.trim()))
+ {
+ model.add(fieldName);
+ l.setSelectedIndex(model.indexOf(fieldName));
+ }
+
+ }
+ else if ("Remove".equals(who) )
+ {
+ ListBox l = context.get("/fields");
+ int sel = l.getSelectedIndex();
+ if ( sel != -1 )
+ {
+ ((ListDataModel)l.getModel()).remove(sel);
+ l.setSelectedIndex(sel-1 < 0 ? 0: sel-1);
+ }
+
+ }
+ else if ("Up".equals(who) )
+ {
+ ListBox l = context.get("/fields");
+ int sel = l.getSelectedIndex();
+ if ( sel != -1 ) {
+ ((ListDataModel)l.getModel()).moveUp(sel);
+ l.setSelectedIndex(sel-1 < 0 ? 0: sel-1);
+ }
+
+ }
+ else if ("Down".equals(who) )
+ {
+ ListBox l = context.get("/fields");
+ int sel = l.getSelectedIndex();
+ if ( sel != -1 ) {
+ ListDataModel model = (ListDataModel)l.getModel();
+ model.moveDown(sel);
+ l.setSelectedIndex(sel+1 > model.size()-1 ? model.size()-1 : sel+1);
+ }
+ }
+ else if ("Rename".equals(who) )
+ {
+ Field f = context.get("/fieldName");
+ ListBox l = context.get("/fields");
+ ListDataModel model = (ListDataModel)l.getModel();
+ String fieldName = f.getText();
+ int sel = l.getSelectedIndex();
+ if ( sel != -1 && fieldName != null && (fieldName.trim().length() > 0) &&
+ !model.contains(fieldName.trim()))
+ {
+ HashObject vals = l.getProperty((String)l.getSelectedValue());
+ if ( vals != null )
+ {
+ l.setProperty(fieldName, vals);
+ l.setProperty("lastSel", fieldName);
+ }
+
+ model.set(sel, fieldName);
+ l.setSelectedIndex(model.indexOf(fieldName));
+
+ }
+ }
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/createTableState.ajl b/extra/jheidi/createTableState.ajl
new file mode 100644
index 00000000..341bf0d5
--- /dev/null
+++ b/extra/jheidi/createTableState.ajl
@@ -0,0 +1,30 @@
+
+ WindowContext context = argObj("windowContext");
+ ListBox l = context.get("/fields");
+
+ HashObject ho = l.getProperty(arg("fieldKey"));
+
+ log.debug("storing props for: " + arg("fieldKey"));
+
+ //put all values in col map
+ ho.put("type", ((Combo)context.get("/types")).getText());
+ ho.put("length", ((Field)context.get("/lengthSet")).getText());
+ ho.put("default", ((Field)context.get("/defaultValue")).getText());
+ ho.put("primary", ((CheckBox)context.get("/primary")).isSelected());
+ ho.put("unique", ((CheckBox)context.get("/unique")).isSelected());
+ ho.put("index", ((CheckBox)context.get("/index")).isSelected());
+ ho.put("notNull", ((CheckBox)context.get("/notNull")).isSelected());
+ ho.put("autoInc", ((CheckBox)context.get("/autoInc")).isSelected());
+ ho.put("binary", ((CheckBox)context.get("/binary")).isSelected());
+ ho.put("unsigned", ((CheckBox)context.get("/unsigned")).isSelected());
+ ho.put("zeroFill", ((CheckBox)context.get("/zeroFill")).isSelected());
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/dropField.ajl b/extra/jheidi/dropField.ajl
new file mode 100644
index 00000000..aa396744
--- /dev/null
+++ b/extra/jheidi/dropField.ajl
@@ -0,0 +1,12 @@
+
+WindowContext context = argObj("windowContext");
+String field = arg("fieldToDrop");
+
+DB db = context.get("db");
+
+db.begin();
+db.execute("use " + context.get("currentDB"));
+db.execute("alter table " + context.get("currentTable") + " drop column " + field);
+db.end();
+
+
diff --git a/extra/jheidi/dropTable.ajl b/extra/jheidi/dropTable.ajl
new file mode 100644
index 00000000..48eef770
--- /dev/null
+++ b/extra/jheidi/dropTable.ajl
@@ -0,0 +1,12 @@
+
+WindowContext context = argObj("windowContext");
+String table = arg("tableToDrop");
+
+DB db = context.get("db");
+
+db.begin();
+db.execute("use " + context.get("currentDB"));
+db.execute("drop table " + table);
+db.end();
+
+
diff --git a/extra/jheidi/fieldDialog.ajl b/extra/jheidi/fieldDialog.ajl
new file mode 100755
index 00000000..e7b84c1d
--- /dev/null
+++ b/extra/jheidi/fieldDialog.ajl
@@ -0,0 +1,133 @@
+ import javax.swing.*;
+ import java.util.*;
+
+ WindowContext parentContext = argObj("windowContext");
+
+ Dialog dlg = new Dialog((Frame)parentContext.get("/"), "fieldDialog", arg("fieldMode") + " Field" );
+ WindowContext context = dlg.getWindowContext();
+ context.put("db", parentContext.get("db"));
+ context.put("currentDB", parentContext.get("currentDB"));
+ context.put("currentTable", parentContext.get("currentTable"));
+ context.put("fieldMode", arg("fieldMode"));
+
+ dlg.events("fieldEvents");
+ dlg.tabLayout();
+ dlg.insets(10, 10);
+ dlg.text("Position:", 90)
+ .setTab()
+ .combo("positions", new String[] {"Hi"}, 200)
+ .setTab()
+ .nextRow()
+ .tab(1)
+ .text("Name:")
+ .tab(2)
+ .field("fieldName", 200)
+ .nextRow()
+ .tab(1)
+ .text("Type:")
+ .tab(2)
+ .combo("types", new String[] {"Hi"}, 200)
+ .nextRow()
+ .tab(1)
+ .text("Length/Set:")
+ .tab(2)
+ .field("lengthSet", 200)
+ .nextRow()
+ .tab(1)
+ .text("Default:")
+ .tab(2)
+ .field("defaultValue", 200)
+ .nextRow()
+ .tab(1)
+ .text("Comment:")
+ .tab(2)
+ .field("comment", 200)
+ .nextRow()
+ .space(-2)
+ .groupbox("Attributes",LF.isWin?302:301, 87)
+ .nextRow()
+ .vspace(17)
+ .space(LF.isWin?18:13)
+ .checkbox("notNull", "Not Null", 90, false)
+ .setTab()
+ .checkbox("autoInc", "Auto Increment", false)
+ .setTab()
+ .nextRow()
+ .tab(3)
+ .checkbox("binary", "Binary", 90, false)
+ .tab(4)
+ .checkbox("unsigned", "Unsigned", 95,false)
+ .space(2)
+ .checkbox("zeroFill", "Zero Fill", 77, false)
+ .nextRow()
+ .vspace(18)
+ .space(37)
+ .button(arg("fieldMode").equals("Add") ?"Add Field" : "Update Field", 110)
+ .space(5)
+ .button("Cancel", 110);
+
+ DB db = context.get("db");
+ db.begin();
+ db.execute("use " + (String)context.get("currentDB"));
+ DB.Result result = db.execute("show full columns from " + (String) context.get("currentTable"));
+ db.end();
+
+ Combo positions = context.get("/positions");
+ String selField = arg("fieldToEdit");
+ context.put("fieldToEdit", selField);
+ HashObject selectField = null;
+ String[] posList = new String[result.size() + (selField == null ?2 :3)];
+ int c = 0;
+ if ( selField != null )
+ {
+ posList[c++] = "";
+ }
+ posList[c++] = "Last";
+ posList[c++] = "First";
+ for (int i=0; i < result.size(); i++)
+ {
+ posList[i+c] = "After '" + result.get(i).get(0) + "'";
+ if ( result.get(i).get(0).equals(selField) )
+ {
+ selectField = (HashObject)result.get(i);
+ }
+
+ }
+
+ positions.setModel(new DefaultComboBoxModel(posList));
+
+ ((Field)context.get("/fieldName")).setText("FieldName");
+ ((JCheckBox)context.get("/autoInc")).setEnabled(false);
+
+ HashObject newArgs = new HashObject();
+ newArgs.put("windowContext", context);
+ script("initMySQLTypes", newArgs);
+
+ if ( selectField != null )
+ { //populate the dialog
+
+ ((Field)context.get("/fieldName")).setText(selectField.get("field"));
+ String type = selectField.get("type");
+ int paren = type.indexOf("(");
+ String typeOnly = paren !=-1 ? type.substring(0, paren) : type.substring(0, type.indexOf(" "));
+ ((Combo)context.get("/types")).select(typeOnly);
+ if ( paren != -1 )
+ {
+ ((Field)context.get("/lengthSet")).setText(type.substring(paren+1, type.indexOf(")")));
+ }
+ ((Field)context.get("/defaultValue")).setText(selectField.get("default")!= null ? selectField.get("default") : "");
+ ((Field)context.get("/comment")).setText(selectField.get("comment")!= null ? selectField.get("comment") : "");
+ ((JCheckBox)context.get("/binary")).setSelected(type.contains("binary"));
+ ((JCheckBox)context.get("/unsigned")).setSelected(type.contains("unsigned"));
+ ((JCheckBox)context.get("/zeroFill")).setSelected(type.contains("zerofill"));
+ ((JCheckBox)context.get("/notNull")).setSelected(selectField.get("null").equals("NO"));
+ ((JCheckBox)context.get("/autoInc")).setSelected(selectField.get("extra") != null &&
+ selectField.get("extra").contains("auto_increment"));
+ }
+
+
+ dlg.visible();
+
+ return context.get("dlgResult");
+
+
diff --git a/extra/jheidi/fieldEvents.ajl b/extra/jheidi/fieldEvents.ajl
new file mode 100644
index 00000000..62021267
--- /dev/null
+++ b/extra/jheidi/fieldEvents.ajl
@@ -0,0 +1,93 @@
+ import javax.swing.*;
+
+ String who = arg("source");
+ WindowContext context = argObj("windowContext");
+ log.debug("event received" + who);
+
+ if ( "Add Field".equals(who) || "Update Field".equals(who) )
+ {
+ Dialog d = context.get("/");
+
+ StringBuilder buffer = new StringBuilder(1000);
+
+ String fieldName = ((Field)context.get("/fieldName")).getText();
+ String dbName = (String)context.get("currentDB");
+ String tableName = (String)context.get("currentTable");
+ String position = ((Combo)context.get("/positions")).getText();
+ String lengthSet = ((Field)context.get("/lengthSet")).getText();
+ String defValue = ((Field)context.get("/defaultValue")).getText();
+ String comment = ((Field)context.get("/comment")).getText();
+
+ if ( fieldName == null || fieldName.trim().length() == 0 )
+ {
+ d.popupMessage(who, "Please provide a field name before saving.");
+ return;
+ }
+
+
+ buffer.append("alter table ").append(tableName);
+ if ( who.startsWith("Add") )
+ {
+ buffer.append(" add ").append(fieldName);
+ }
+ else
+ {
+ buffer.append(" change ").append(context.get("fieldToEdit")).append(" ").append(fieldName);
+ }
+ buffer.append(" ").append(((Combo)context.get("/types")).getText());
+ if ( lengthSet != null && lengthSet.trim().length() > 0)
+ {
+ buffer.append("(").append(lengthSet.trim()).append(")");
+ }
+ if ( ((JCheckBox)context.get("/binary")).isSelected() )
+ buffer.append(" binary");
+ if ( ((JCheckBox)context.get("/unsigned")).isSelected() )
+ buffer.append(" unsigned");
+ if ( ((JCheckBox)context.get("/zeroFill")).isSelected() )
+ buffer.append(" zerofill");
+
+ if ( defValue != null && defValue.trim().length() > 0)
+ {
+ buffer.append(" default '").append(defValue.trim()).append("'");
+ }
+
+ if ( ((JCheckBox)context.get("/notNull")).isSelected() )
+ buffer.append(" not null");
+
+ if ( comment != null & comment.trim().length() > 0 )
+ {
+ buffer.append(" comment '").append(comment.trim()).append("'");
+ }
+
+ if ( !position.equals("Last") )
+ {
+ buffer.append(" ").append(position);
+ }
+
+ // ALTER TABLE `tablename` ADD `turd` TINYINT(5) UNSIGNED ZEROFILL DEFAULT 'wow' NOT NULL COMMENT 'comment'
+ log.debug("heres the statement: " + buffer.toString());
+ DB db = context.get("db");
+ db.begin();
+ db.execute("use " + context.get("currentDB"));
+ db.execute(buffer.toString());
+ db.end();
+
+
+ context.put("dlgResult", Boolean.TRUE);
+
+ d.dispose();
+
+ }
+ else if ( "Cancel".equals(who) )
+ {
+ Dialog d = context.get("/");
+ d.dispose();
+ }
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/fieldListEvents.ajl b/extra/jheidi/fieldListEvents.ajl
new file mode 100644
index 00000000..69b600e2
--- /dev/null
+++ b/extra/jheidi/fieldListEvents.ajl
@@ -0,0 +1,62 @@
+ import javax.swing.*;
+
+ WindowContext context = argObj("windowContext");
+ ListBox l = context.get("/fields");
+ String lastSel = l.getProperty("lastSel");
+ String item = (String)l.getSelectedValue();
+
+
+ if ( lastSel == null )
+ {
+ l.setProperty("lastSel", item);
+ HashObject ho = new HashObject();
+ ho.put("colName", item);
+ l.setProperty(item, ho);
+ }
+ else
+ {
+ if ( !lastSel.equals(item) )
+ {
+ args().put("fieldKey", lastSel);
+ script("createTableState", args());
+
+ l.setProperty("lastSel", item);
+ HashObject ho = l.getProperty(item);
+ log.debug("getting props for: " + item);
+ if ( ho != null )
+ {
+ log.debug("populating props for: " + item);
+ ((Combo)context.get("/types")).select(ho.get("type"));
+ ((Field)context.get("/lengthSet")).setText(ho.get("length"));
+ ((Field)context.get("/defaultValue")).setText(ho.get("default"));
+ ((JCheckBox)context.get("/primary")).setSelected((Boolean)ho.getObject("primary"));
+ ((JCheckBox)context.get("/unique")).setSelected((Boolean)ho.getObject("unique"));
+ ((JCheckBox)context.get("/index")).setSelected((Boolean)ho.getObject("index"));
+ ((JCheckBox)context.get("/notNull")).setSelected((Boolean)ho.getObject("notNull"));
+ ((JCheckBox)context.get("/autoInc")).setSelected((Boolean)ho.getObject("autoInc"));
+ ((JCheckBox)context.get("/binary")).setSelected((Boolean)ho.getObject("binary"));
+ ((JCheckBox)context.get("/unsigned")).setSelected((Boolean)ho.getObject("unsigned"));
+ ((JCheckBox)context.get("/zeroFill")).setSelected((Boolean)ho.getObject("zeroFill"));
+ }
+ else
+ {
+ log.debug("no props yet for: " + item + " clearing fields setting new props");
+ //set the type to clear the fields
+ ((Combo)context.get("/types")).setProperty("currentCheckState", null);
+ ((Combo)context.get("/types")).select(((Combo)context.get("/types")).getText());
+ l.setProperty(item, new HashObject());
+ }
+
+
+
+ }
+ }
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/images/alt/clear.gif b/extra/jheidi/images/alt/clear.gif
new file mode 100755
index 00000000..25583265
Binary files /dev/null and b/extra/jheidi/images/alt/clear.gif differ
diff --git a/extra/jheidi/images/clear.gif b/extra/jheidi/images/clear.gif
new file mode 100755
index 00000000..25583265
Binary files /dev/null and b/extra/jheidi/images/clear.gif differ
diff --git a/extra/jheidi/images/connect.gif b/extra/jheidi/images/connect.gif
new file mode 100755
index 00000000..9a2594bf
Binary files /dev/null and b/extra/jheidi/images/connect.gif differ
diff --git a/extra/jheidi/images/copy.gif b/extra/jheidi/images/copy.gif
new file mode 100755
index 00000000..71d7c95a
Binary files /dev/null and b/extra/jheidi/images/copy.gif differ
diff --git a/extra/jheidi/images/cut.gif b/extra/jheidi/images/cut.gif
new file mode 100755
index 00000000..0d961dd2
Binary files /dev/null and b/extra/jheidi/images/cut.gif differ
diff --git a/extra/jheidi/images/data.gif b/extra/jheidi/images/data.gif
new file mode 100644
index 00000000..59010450
Binary files /dev/null and b/extra/jheidi/images/data.gif differ
diff --git a/extra/jheidi/images/db-center.gif b/extra/jheidi/images/db-center.gif
new file mode 100644
index 00000000..195a3cab
Binary files /dev/null and b/extra/jheidi/images/db-center.gif differ
diff --git a/extra/jheidi/images/db.gif b/extra/jheidi/images/db.gif
new file mode 100644
index 00000000..7c5b81e0
Binary files /dev/null and b/extra/jheidi/images/db.gif differ
diff --git a/extra/jheidi/images/deletedb.gif b/extra/jheidi/images/deletedb.gif
new file mode 100644
index 00000000..a58afc3c
Binary files /dev/null and b/extra/jheidi/images/deletedb.gif differ
diff --git a/extra/jheidi/images/deletefield.gif b/extra/jheidi/images/deletefield.gif
new file mode 100755
index 00000000..3e9d8933
Binary files /dev/null and b/extra/jheidi/images/deletefield.gif differ
diff --git a/extra/jheidi/images/deletetable.gif b/extra/jheidi/images/deletetable.gif
new file mode 100644
index 00000000..b23eaa4b
Binary files /dev/null and b/extra/jheidi/images/deletetable.gif differ
diff --git a/extra/jheidi/images/disconnect.gif b/extra/jheidi/images/disconnect.gif
new file mode 100755
index 00000000..0994e248
Binary files /dev/null and b/extra/jheidi/images/disconnect.gif differ
diff --git a/extra/jheidi/images/domain.gif b/extra/jheidi/images/domain.gif
new file mode 100755
index 00000000..bb2d7946
Binary files /dev/null and b/extra/jheidi/images/domain.gif differ
diff --git a/extra/jheidi/images/down.gif b/extra/jheidi/images/down.gif
new file mode 100644
index 00000000..072b1844
Binary files /dev/null and b/extra/jheidi/images/down.gif differ
diff --git a/extra/jheidi/images/e_contents_view.gif b/extra/jheidi/images/e_contents_view.gif
new file mode 100644
index 00000000..9e665d5c
Binary files /dev/null and b/extra/jheidi/images/e_contents_view.gif differ
diff --git a/extra/jheidi/images/editfield.gif b/extra/jheidi/images/editfield.gif
new file mode 100755
index 00000000..8048405a
Binary files /dev/null and b/extra/jheidi/images/editfield.gif differ
diff --git a/extra/jheidi/images/export.gif b/extra/jheidi/images/export.gif
new file mode 100644
index 00000000..7f98c334
Binary files /dev/null and b/extra/jheidi/images/export.gif differ
diff --git a/extra/jheidi/images/folder.gif b/extra/jheidi/images/folder.gif
new file mode 100755
index 00000000..03ee1dcb
Binary files /dev/null and b/extra/jheidi/images/folder.gif differ
diff --git a/extra/jheidi/images/help.gif b/extra/jheidi/images/help.gif
new file mode 100644
index 00000000..1ee5b6aa
Binary files /dev/null and b/extra/jheidi/images/help.gif differ
diff --git a/extra/jheidi/images/icallout_obj.gif b/extra/jheidi/images/icallout_obj.gif
new file mode 100644
index 00000000..f52d86a6
Binary files /dev/null and b/extra/jheidi/images/icallout_obj.gif differ
diff --git a/extra/jheidi/images/import.gif b/extra/jheidi/images/import.gif
new file mode 100644
index 00000000..1160e843
Binary files /dev/null and b/extra/jheidi/images/import.gif differ
diff --git a/extra/jheidi/images/instance.gif b/extra/jheidi/images/instance.gif
new file mode 100755
index 00000000..b2361a3a
Binary files /dev/null and b/extra/jheidi/images/instance.gif differ
diff --git a/extra/jheidi/images/left.gif b/extra/jheidi/images/left.gif
new file mode 100755
index 00000000..4fb41501
Binary files /dev/null and b/extra/jheidi/images/left.gif differ
diff --git a/extra/jheidi/images/manageindexes.gif b/extra/jheidi/images/manageindexes.gif
new file mode 100644
index 00000000..2ccbbbaf
Binary files /dev/null and b/extra/jheidi/images/manageindexes.gif differ
diff --git a/extra/jheidi/images/mysql-logo.gif b/extra/jheidi/images/mysql-logo.gif
new file mode 100644
index 00000000..68e84124
Binary files /dev/null and b/extra/jheidi/images/mysql-logo.gif differ
diff --git a/extra/jheidi/images/newfield.gif b/extra/jheidi/images/newfield.gif
new file mode 100755
index 00000000..7d24707e
Binary files /dev/null and b/extra/jheidi/images/newfield.gif differ
diff --git a/extra/jheidi/images/paste.gif b/extra/jheidi/images/paste.gif
new file mode 100755
index 00000000..39dd4d9d
Binary files /dev/null and b/extra/jheidi/images/paste.gif differ
diff --git a/extra/jheidi/images/print.gif b/extra/jheidi/images/print.gif
new file mode 100644
index 00000000..04cb84bf
Binary files /dev/null and b/extra/jheidi/images/print.gif differ
diff --git a/extra/jheidi/images/query.gif b/extra/jheidi/images/query.gif
new file mode 100755
index 00000000..8e847163
Binary files /dev/null and b/extra/jheidi/images/query.gif differ
diff --git a/extra/jheidi/images/refresh.gif b/extra/jheidi/images/refresh.gif
new file mode 100755
index 00000000..9f6c9b18
Binary files /dev/null and b/extra/jheidi/images/refresh.gif differ
diff --git a/extra/jheidi/images/relaunchf.gif b/extra/jheidi/images/relaunchf.gif
new file mode 100644
index 00000000..c8c89916
Binary files /dev/null and b/extra/jheidi/images/relaunchf.gif differ
diff --git a/extra/jheidi/images/right.gif b/extra/jheidi/images/right.gif
new file mode 100755
index 00000000..e2f8c3e1
Binary files /dev/null and b/extra/jheidi/images/right.gif differ
diff --git a/extra/jheidi/images/run.gif b/extra/jheidi/images/run.gif
new file mode 100755
index 00000000..8174dade
Binary files /dev/null and b/extra/jheidi/images/run.gif differ
diff --git a/extra/jheidi/images/runselection.gif b/extra/jheidi/images/runselection.gif
new file mode 100644
index 00000000..ad88296b
Binary files /dev/null and b/extra/jheidi/images/runselection.gif differ
diff --git a/extra/jheidi/images/save.gif b/extra/jheidi/images/save.gif
new file mode 100644
index 00000000..9f695864
Binary files /dev/null and b/extra/jheidi/images/save.gif differ
diff --git a/extra/jheidi/images/saveas.gif b/extra/jheidi/images/saveas.gif
new file mode 100644
index 00000000..f475af54
Binary files /dev/null and b/extra/jheidi/images/saveas.gif differ
diff --git a/extra/jheidi/images/search.gif b/extra/jheidi/images/search.gif
new file mode 100644
index 00000000..1e94a9c6
Binary files /dev/null and b/extra/jheidi/images/search.gif differ
diff --git a/extra/jheidi/images/sqllog.gif b/extra/jheidi/images/sqllog.gif
new file mode 100755
index 00000000..e1f6e5c9
Binary files /dev/null and b/extra/jheidi/images/sqllog.gif differ
diff --git a/extra/jheidi/images/stop.gif b/extra/jheidi/images/stop.gif
new file mode 100755
index 00000000..dc47edf0
Binary files /dev/null and b/extra/jheidi/images/stop.gif differ
diff --git a/extra/jheidi/images/table.gif b/extra/jheidi/images/table.gif
new file mode 100755
index 00000000..b99b45ca
Binary files /dev/null and b/extra/jheidi/images/table.gif differ
diff --git a/extra/jheidi/images/up.gif b/extra/jheidi/images/up.gif
new file mode 100644
index 00000000..07164754
Binary files /dev/null and b/extra/jheidi/images/up.gif differ
diff --git a/extra/jheidi/images/vista/instance.gif b/extra/jheidi/images/vista/instance.gif
new file mode 100755
index 00000000..95cb5ac2
Binary files /dev/null and b/extra/jheidi/images/vista/instance.gif differ
diff --git a/extra/jheidi/images/vista/sqllog.gif b/extra/jheidi/images/vista/sqllog.gif
new file mode 100755
index 00000000..4a748d2b
Binary files /dev/null and b/extra/jheidi/images/vista/sqllog.gif differ
diff --git a/extra/jheidi/indexDialog.ajl b/extra/jheidi/indexDialog.ajl
new file mode 100755
index 00000000..bce485c6
--- /dev/null
+++ b/extra/jheidi/indexDialog.ajl
@@ -0,0 +1,105 @@
+ import javax.swing.*;
+
+ WindowContext parentContext = argObj("windowContext");
+
+ Dialog dlg = new Dialog((Frame)parentContext.get("/"), "indexDialog", "Manage Indexes");
+ WindowContext context = dlg.getWindowContext();
+ context.put("db", parentContext.get("db"));
+ context.put("currentDB", parentContext.get("currentDB"));
+ context.put("currentTable", parentContext.get("currentTable"));
+
+ dlg.events("indexEvents");
+ dlg.insets(10,10);
+ dlg.tabLayout();
+ dlg.text("Index Name:", 89)
+ .setTab()
+ .combo("indexes", new String[] {"", "Hi"}, 243)
+ .setTab()
+ .nextRow()
+ .tab(2)
+ .button("Add Primary", LF.isLeopard?101:100)
+ .button("Add", 65)
+ .button("Delete", 65)
+ .nextRow()
+ .vspace(5)
+ .tab(1)
+ .checkbox("unique", "Unique", false, true)
+ .tab(2)
+ .checkbox("fullText", "FullText", false, true)
+ .nextRow()
+ .tab(1)
+ .text("Columns:", 183)
+ .setTab()
+ .text("Columns In Index:", 150)
+ .setTab()
+ .nextRow()
+ .tab(1)
+ .listbox("fields", new String[] {}, 150, 200 )
+ .vspace(50)
+ .space(-1)
+ .imageButton("right", "images/right.gif", 28)
+ .vspace(0)
+ .space(-35)
+ .vspace(90)
+ .imageButton("left", "images/left.gif", 28)
+ .vspace(0)
+ .tab(4)
+ .listbox("indexFields", new String[] {}, 150, 200 )
+ .nextRow()
+ .vspace(205)
+ .space(45)
+ .button("Update Indexes", LF.isMac?LF.isLeopard?123:122:120)
+ .space(5)
+ .button("Cancel", 110);
+
+ DB db = context.get("db");
+ db.begin();
+ db.execute("use " + (String)context.get("currentDB"));
+ DB.Result result = db.execute("show keys from " + (String) context.get("currentTable"));
+ DB.Result allColumns = db.execute("show columns from " + context.get("currentTable"));
+ db.end();
+
+ Combo indexes = context.get("/indexes");
+ HashObject indexMap = new HashObject();
+ for (HashObject index: result)
+ {
+ if ( indexMap.getObject(index.get("key_name")) == null )
+ {
+ indexMap.put(index.get("key_name"), new HashObject());
+ }
+ ((HashObject)indexMap.getObject(index.get("key_name"))).put(index.get("column_name"), index);
+ }
+
+ String[] allCols = new String[allColumns.size()];
+ for (int i=0; i < allColumns.size(); i++)
+ {
+ allCols[i] = ((HashObject)allColumns.get(i)).get("field");
+ }
+
+ Object[] keys = indexMap.keySet().toArray();
+
+ indexes.setModel(new DefaultComboBoxModel(keys));
+ indexes.setProperty("indexMap", indexMap);
+ indexes.setProperty("allColumns", allCols);
+ indexes.setProperty("storedValues", new HashObject());
+
+ if ( keys.length > 0 )
+ {
+ indexes.select((String)keys[0]);
+ }
+
+ if ( indexMap.getObject("PRIMARY") != null )
+ {
+ ((Button)context.get("/Add Primary")).setEnabled(false);
+ }
+
+ if ( indexMap.size() == 0 )
+ {
+ ((Button)context.get("/Delete")).setEnabled(false);
+ }
+
+ dlg.visible();
+
+ return context.get("dlgResult");
+
+
diff --git a/extra/jheidi/indexEvents.ajl b/extra/jheidi/indexEvents.ajl
new file mode 100755
index 00000000..64d609ef
--- /dev/null
+++ b/extra/jheidi/indexEvents.ajl
@@ -0,0 +1,357 @@
+ import javax.swing.*;
+ import java.util.*;
+
+ String who = arg("source");
+ WindowContext context = argObj("windowContext");
+ log.debug("event received: " + who);
+
+ ListBox indexFields = context.get("/indexFields");
+ ListBox fields = context.get("/fields");
+ Combo indexes = context.get("/indexes");
+
+
+ if ("unique".equals(who))
+ {
+ ((CheckBox)context.get("/fullText")).setSelected(false);
+ }
+ else if ("fullText".equals(who))
+ {
+ ((CheckBox)context.get("/unique")).setSelected(false);
+ }
+ else if ("Add Primary".equals(who))
+ {
+ DefaultComboBoxModel model = (DefaultComboBoxModel)indexes.getModel();
+ model.addElement("PRIMARY");
+ model.setSelectedItem("PRIMARY");
+ ((Button)context.get("/Delete")).setEnabled(true);
+ ((Button)context.get("/Add Primary")).setEnabled(false);
+ }
+ else if ("Add".equals(who))
+ {
+ Dialog d = context.get("/");
+
+ String newIndex = d.popupQuestion("Add Index", "Enter a name for the new index:");
+ if ( newIndex != null && newIndex.trim().length() > 0)
+ {
+ DefaultComboBoxModel model = (DefaultComboBoxModel)indexes.getModel();
+ newIndex = newIndex.trim().toLowerCase();
+ if ( model.getIndexOf( newIndex ) != -1 )
+ {
+ d.popupMessage("Invalid Index Name", "That index name already exists.");
+ }
+ else
+ {
+ model.addElement(newIndex);
+ model.setSelectedItem(newIndex);
+ ((Button)context.get("/Delete")).setEnabled(true);
+ }
+
+ }
+
+ }
+ else if ("Delete".equals(who))
+ {
+ Dialog d = context.get("/");
+ String indexToDelete = indexes.getText();
+
+ if (d.popupConfirm("Confirm Delete!", "Are you sure you want to delete index '" + indexToDelete + "'?"))
+ {
+ ((DefaultComboBoxModel)indexes.getModel()).removeElement(indexToDelete);
+ if ( ((DefaultComboBoxModel)indexes.getModel()).getSize() == 0 )
+ {
+ ((Button)context.get("/Delete")).setEnabled(false);
+ }
+ if ( "PRIMARY".equals(indexToDelete) )
+ {
+ ((Button)context.get("/Add Primary")).setEnabled(true);
+ }
+
+ HashObject storedVals = indexes.getProperty("storedValues");
+ HashObject indexMap = indexes.getProperty("indexMap");
+
+ if ( indexMap.getObject(indexToDelete) != null )
+ {
+ storedVals.remove(storedVals.getObject(indexToDelete));
+ storedVals.keySet().remove(indexToDelete);
+ context.put("lastIndex", null);
+ }
+
+ }
+ }
+ else if ("Update Indexes".equals(who))
+ {
+ String indexName = indexes.getText();
+ List deletes = new ArrayList();
+ List adds = new ArrayList();
+ HashObject indexMap = indexes.getProperty("indexMap");
+ HashObject storedVals = indexes.getProperty("storedValues");
+
+ //flush the view to storage
+ if ( indexName != null )
+ {
+ log.debug("index selected in combo: storing to hash");
+ HashObject h = storedVals.getObject(indexName) == null ?
+ (HashObject)new HashObject() : (HashObject)storedVals.getObject(indexName);
+ h.put("indexListModel", indexFields.getModel());
+ h.put("fieldListModel", fields.getModel());
+ h.put("unique", new Boolean(((CheckBox)context.get("/unique")).isSelected()));
+ h.put("fullText", new Boolean(((CheckBox)context.get("/fullText")).isSelected()));
+ storedVals.put(indexName, h);
+ }
+
+ log.debug("iterating indexes combo count: " + indexes.getItemCount());
+ for ( int i=0; i < indexes.getItemCount(); i++ )
+ {
+ indexName = (String)indexes.getItemAt(i);
+ HashObject index = (HashObject)indexMap.getObject(indexName);
+ HashObject storedIndex = (HashObject)storedVals.getObject(indexName);
+
+ if ( index == null )
+ {
+ log.debug("added index: " + indexName);
+ //storedIndex cannot be null for adds
+ ListDataModel listModel = storedIndex.getObject("indexListModel");
+ if ( listModel.size() > 0 )
+ {
+ adds.add(indexName);
+ }
+ else
+ {
+ log.debug("skipping index with no cols: " + indexName);
+ }
+
+ }
+ else if ( storedIndex != null )
+ {
+ log.debug("diffing: " + indexName);
+ boolean isUnique = "0".equals(((HashObject)index.get(0)).get("non_unique"));
+ boolean isFullText = "FULLTEXT".equals(((HashObject)index.get(0)).get("index_type"));
+
+ ListDataModel listModel = storedIndex.getObject("indexListModel");
+
+ if ( listModel.size() == 0 )
+ {
+ log.debug("skipping index with no cols: " + indexName);
+ continue;
+ }
+
+ if ( listModel.size() != index.size() ||
+ !((Boolean)storedIndex.getObject("unique")).equals(Boolean.valueOf(isUnique)) ||
+ !((Boolean)storedIndex.getObject("fullText")).equals(Boolean.valueOf(isFullText)) )
+ {
+ deletes.add(indexName);
+ adds.add(indexName);
+ break;
+ }
+ else
+ {
+ int count = 0;
+ for (HashObject col : (List)index )
+ {
+ if ( !col.get("column_name").equals( listModel.get(count) ) )
+ {
+ deletes.add(indexName);
+ adds.add(indexName);
+ break;
+ }
+ }
+ }
+ log.debug("no changes to: " + indexName);
+ }
+ }
+
+ for ( String key: (Set)indexMap.keySet() )
+ {
+ if ( ((DefaultComboBoxModel)indexes.getModel()).getIndexOf(key) == -1 )
+ {
+ log.debug("deleted: " + key);
+ deletes.add( key );
+ }
+ }
+
+ if ( deletes.size() > 0 || adds.size() > 0 )
+ {
+ log.debug("changes were made - generating statement");
+ //ALTER TABLE `tablename` DROP INDEX `NewIndex`, ADD FULLTEXT `NewIndex` (`another`, `FieldName`, `whoever`)
+ StringBuilder buffer = new StringBuilder(500);
+ buffer.append("alter table ").append(context.get("currentTable"));
+
+ String sep=" ";
+ for (String ndx : deletes)
+ {
+ if ( "PRIMARY".equals(ndx) )
+ {
+ buffer.append(sep).append("drop primary key");
+ }
+ else
+ {
+ buffer.append(sep).append("drop index ").append(ndx);
+ }
+ sep=", ";
+ }
+ for (String ndx : adds)
+ {
+ log.debug("iterating adds: added: " + ndx);
+ HashObject storedIndex = (HashObject)storedVals.getObject(ndx);
+ ListDataModel listModel = storedIndex.getObject("indexListModel");
+
+ buffer.append(sep).append("add ");
+ if ("PRIMARY".equals(ndx))
+ {
+ buffer.append("primary key ");
+ }
+ else if (Boolean.TRUE.equals((Boolean)storedIndex.getObject("unique")))
+ {
+ buffer.append("unique ").append(ndx);
+ }
+ else if (Boolean.TRUE.equals((Boolean)storedIndex.getObject("fullText")))
+ {
+ buffer.append("fulltext ").append(ndx);
+ }
+ else
+ {
+ buffer.append(ndx);
+ }
+ buffer.append(" (");
+
+ String sep2="";
+ for (String colName : listModel)
+ {
+ buffer.append(sep2).append(colName);
+ sep2=", ";
+ }
+ buffer.append(")");
+ sep=", ";
+ }
+ log.debug("The sql is: " + buffer.toString());
+
+ DB db = context.get("db");
+ db.begin();
+ db.execute("use " + context.get("currentDB"));
+ db.execute(buffer.toString());
+ db.end();
+
+ context.put("dlgResult", Boolean.TRUE);
+
+ }
+ ((Dialog)context.get("/")).dispose();
+
+ }
+ else if ( "indexes".equals(who) )
+ {
+ //this must diff the avail cols with the cols in index
+ //keeping both in order shifitng in and out as the user changes sel
+ if ( indexes.getText() == null )
+ {
+ //user deleted all indexes?
+ indexFields.setModel(new ListDataModel(new String[0]));
+ fields.setModel(new ListDataModel(new String[0]));
+ return;
+ }
+ if ( !indexes.getText().equals(context.get("lastIndex")))
+ {
+ HashObject indexMap = indexes.getProperty("indexMap");
+ HashObject storedVals = indexes.getProperty("storedValues");
+
+ if ( context.get("lastIndex") != null )
+ {
+ String indexName = context.get("lastIndex");
+ //store the last indexes properties
+ HashObject h = storedVals.getObject(indexName) == null ? (HashObject)new HashObject() : (HashObject)storedVals.getObject(indexName);
+
+ h.put("indexListModel", indexFields.getModel());
+ h.put("fieldListModel", fields.getModel());
+ h.put("unique", new Boolean(((CheckBox)context.get("/unique")).isSelected()));
+ h.put("fullText", new Boolean(((CheckBox)context.get("/fullText")).isSelected()));
+ storedVals.put(indexName, h);
+ }
+
+ HashObject index = (HashObject)indexMap.getObject(indexes.getText());
+ if ( storedVals.getObject(indexes.getText()) != null )
+ {
+ HashObject h = storedVals.getObject(indexes.getText());
+ indexFields.setModel((ListDataModel)h.getObject("indexListModel"));
+ fields.setModel((ListDataModel)h.getObject("fieldListModel"));
+ ((CheckBox)context.get("/unique")).setSelected((Boolean)h.getObject("unique"));
+ ((CheckBox)context.get("/fullText")).setSelected((Boolean)h.getObject("fullText"));
+ }
+ else
+ {
+ String[] allCols = indexes.getProperty("allColumns");
+
+ List cols = new ArrayList();
+ List indexCols = new ArrayList();
+
+ boolean isUnique = index != null && "0".equals(((HashObject)index.get(0)).get("non_unique"));
+ boolean isFullText = index != null && "FULLTEXT".equals(((HashObject)index.get(0)).get("index_type"));
+
+ for (String col: allCols)
+ {
+ if ( index==null || index.getObject(col) == null )
+ {
+ cols.add(col);
+ }
+ }
+ if ( index != null )
+ {
+ for (HashObject h : (List)index)
+ indexCols.add(h.get("column_name"));
+ }
+
+ fields.setModel(new ListDataModel(cols.toArray()));
+ indexFields.setModel(new ListDataModel(indexCols.toArray()));
+ ((CheckBox)context.get("/unique")).setSelected(isUnique);
+ ((CheckBox)context.get("/fullText")).setSelected(isFullText);
+ }
+
+ boolean enableChecks = !"PRIMARY".equals(indexes.getText());
+ ((CheckBox)context.get("/unique")).setEnabled(enableChecks);
+ ((CheckBox)context.get("/fullText")).setEnabled(enableChecks);
+
+ context.put("lastIndex", indexes.getText());
+ }
+
+ }
+ else if ("fields".equals(who) )
+ {
+ if ( fields.getSelectedIndex() > -1 )
+ {
+ indexFields.clearSelection();
+ }
+ }
+ else if ("indexFields".equals(who) )
+ {
+ if ( indexFields.getSelectedIndex() > -1 )
+ {
+ fields.clearSelection();
+ }
+ }
+ else if ("left".equals(who) )
+ {
+ if ( indexFields.getSelectedValue() != null)
+ {
+ ((ListDataModel)fields.getModel()).add(indexFields.getSelectedValue());
+ ((ListDataModel)indexFields.getModel()).remove(indexFields.getSelectedIndex());
+ }
+ }
+ else if ("right".equals(who) )
+ {
+ if ( fields.getSelectedValue() != null)
+ {
+ ((ListDataModel)indexFields.getModel()).add(fields.getSelectedValue());
+ ((ListDataModel)fields.getModel()).remove(fields.getSelectedIndex());
+ }
+ }
+ else if ( "Cancel".equals(who) )
+ {
+ Dialog d = context.get("/");
+ d.dispose();
+ }
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/initDB.ajl b/extra/jheidi/initDB.ajl
new file mode 100644
index 00000000..f4d6ad37
--- /dev/null
+++ b/extra/jheidi/initDB.ajl
@@ -0,0 +1,27 @@
+import com.mysql.jdbc.jdbc2.optional.*;
+import javax.sql.DataSource;
+import com.rendion.editor.*;
+
+DB db = null;
+
+WindowContext context = argObj("windowContext");
+HashObject profile = context.get("profile");
+AjlEditor editor = context.get("/consoleTabs/SQL Log/outputWindow");
+
+try
+{
+ MysqlDataSource ds = new MysqlDataSource();
+ String url = "jdbc:mysql://" + profile.get("host") + ":" + profile.get("port") + "/";
+
+ ds.setUrl(url);
+ ds.setUser(profile.get("user"));
+ ds.setPassword(profile.get("password"));
+
+ db = new SQLLoggingDB((DataSource)ds, editor);
+
+} catch (Exception e) {
+ throw new RuntimeException(e);
+}
+
+context.put("db", db);
+
diff --git a/extra/jheidi/initMySQLTypes.ajl b/extra/jheidi/initMySQLTypes.ajl
new file mode 100644
index 00000000..1a39f308
--- /dev/null
+++ b/extra/jheidi/initMySQLTypes.ajl
@@ -0,0 +1,81 @@
+ import javax.swing.*;
+ import java.util.*;
+
+ WindowContext context = argObj("windowContext");
+
+ Combo types = context.get("/types");
+
+ String[] typesArray = new String[] { "tinyint", "mediumint", "int", "bigint", "float", "double","decimal","date",
+ "time", "year", "datetime", "timestamp", "char", "varchar", "tinytext", "mediumtext", "text", "longtext",
+ "binary", "varbinary", "tinyblob", "blob", "mediumblob", "longblob", "enum", "set", "bit",
+ "point", "linestring", "polygon", "geometry", "multipoint", "multilinestring", "multipolygon",
+ "geometrycollection" };
+
+ types.setModel(new DefaultComboBoxModel(typesArray));
+ types.events("typeChangeEvents");
+
+ Object[] widgets = new Object[] { context.get("/binary"), context.get("/unsigned"), context.get("/zeroFill"),
+ context.get("/lengthSet"), context.get("/defaultValue") };
+
+ // p, i, u, b, u, z, n, a, l
+ int[] ZERO_6 = new int[] { 0, 2, 1, 1, 1 };
+ int[] SEVEN = new int[] { 0, 2, 1, 2, 1 };
+ int[] EIGHT_12 = new int[] { 0, 0, 0, 1, 1 };
+ int[] THIRT_14 = new int[] { 1, 0, 0, 2, 1 };
+ int[] FIFT_18 = new int[] { 1, 0, 0, 0, 0 };
+ int[] NINT_20 = new int[] { 0, 0, 0, 2, 1 };
+ int[] TWEN1_24 = new int[] { 0, 0, 0, 0, 0 };
+ int[] TWEN5_26 = new int[] { 0, 0, 0, 1, 1 };
+ int[] TWEN7 = new int[] { 0, 0, 0, 0, 1 };
+ int[] TWEN8 = new int[] { 0, 0, 0, 0, 1 };
+
+ HashObject typeMap = new HashObject();
+ HashObject defSizeMap = new HashObject();
+
+ types.setProperty("typeStateMap", typeMap);
+ types.setProperty("defSizeMap", defSizeMap);
+ types.setProperty("widgets", widgets);
+
+ for (int i=0; i < typesArray.length; i++)
+ {
+ if (i < 6)
+ typeMap.put(typesArray[i], ZERO_6);
+ else if ( i == 6 )
+ typeMap.put(typesArray[i], SEVEN);
+ else if ( i < 12 )
+ typeMap.put(typesArray[i], EIGHT_12);
+ else if ( i < 14 )
+ typeMap.put(typesArray[i], THIRT_14);
+ else if ( i < 18 )
+ typeMap.put(typesArray[i], FIFT_18);
+ else if ( i < 20 )
+ typeMap.put(typesArray[i], NINT_20);
+ else if ( i < 23 )
+ typeMap.put(typesArray[i], TWEN1_24);
+ else if ( i < 26 )
+ typeMap.put(typesArray[i], TWEN5_26);
+ else if ( i == 26 )
+ typeMap.put(typesArray[i], TWEN7);
+ else
+ typeMap.put(typesArray[i], TWEN8);
+ }
+
+ defSizeMap.put(typesArray[12], "50");
+ defSizeMap.put(typesArray[13], "50");
+ defSizeMap.put(typesArray[18], "50");
+ defSizeMap.put(typesArray[19], "50");
+ defSizeMap.put(typesArray[24], "'Y', 'N'");
+ defSizeMap.put(typesArray[25], "'Y', 'N'");
+ defSizeMap.put(typesArray[26], "'Y', 'N'");
+
+ types.select("tinyint");
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/initTree.ajl b/extra/jheidi/initTree.ajl
new file mode 100644
index 00000000..06397e8f
--- /dev/null
+++ b/extra/jheidi/initTree.ajl
@@ -0,0 +1,47 @@
+
+ WindowContext context = argObj("windowContext");
+ HashObject profile = context.get("profile");
+ Tree tree = context.get("/schemaTree");
+ NodeInfo root = (NodeInfo)tree.getModel().getRoot();
+
+ if ( root.getText().equals("A Tree") )
+ {
+ //we are new and not in a refresh
+ tree.setCellRenderer(new IconicCellRenderer("images/db.gif", "images/instance.gif", "images/table.gif"));
+ root.setText(profile.get("user") + "@" + profile.get("host"));
+ root.setIcon("instance");
+ }
+ root.removeAllChildren();
+
+ DB db = context.get("db");
+ db.begin();
+ DB.Result databases = db.execute("show databases");
+ log.debug("database count:" + databases.size());
+ HashObject dbNodes = TreeUtils.populateList(root, databases, 0, "db");
+
+ for ( HashObject _dbs : databases )
+ {
+ String dbName = (String) _dbs.get(0);
+ DB.Result tables = db.execute("show tables from " + dbName);
+ log.debug("adding tables to node (" + dbName + ") " + dbNodes.getObject(dbName));
+ TreeUtils.populateList((NodeInfo)dbNodes.getObject(dbName), tables, 0, "table");
+ }
+
+ db.end();
+
+ tree.updateUI();
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/lib-src/ajl.jar b/extra/jheidi/lib-src/ajl.jar
new file mode 100644
index 00000000..e91c77a2
Binary files /dev/null and b/extra/jheidi/lib-src/ajl.jar differ
diff --git a/extra/jheidi/lib-src/editor.jar b/extra/jheidi/lib-src/editor.jar
new file mode 100644
index 00000000..fb9be328
Binary files /dev/null and b/extra/jheidi/lib-src/editor.jar differ
diff --git a/extra/jheidi/lib/ajl.jar b/extra/jheidi/lib/ajl.jar
new file mode 100644
index 00000000..5264f84c
Binary files /dev/null and b/extra/jheidi/lib/ajl.jar differ
diff --git a/extra/jheidi/lib/editor.jar b/extra/jheidi/lib/editor.jar
new file mode 100644
index 00000000..18510904
Binary files /dev/null and b/extra/jheidi/lib/editor.jar differ
diff --git a/extra/jheidi/lib/libquaqua.jnilib b/extra/jheidi/lib/libquaqua.jnilib
new file mode 100644
index 00000000..70b49eab
Binary files /dev/null and b/extra/jheidi/lib/libquaqua.jnilib differ
diff --git a/extra/jheidi/lib/log4j-1.2.13.jar b/extra/jheidi/lib/log4j-1.2.13.jar
new file mode 100755
index 00000000..dde99721
Binary files /dev/null and b/extra/jheidi/lib/log4j-1.2.13.jar differ
diff --git a/extra/jheidi/lib/mysql-connector-java-5.0.7-bin.jar b/extra/jheidi/lib/mysql-connector-java-5.0.7-bin.jar
new file mode 100755
index 00000000..412138ab
Binary files /dev/null and b/extra/jheidi/lib/mysql-connector-java-5.0.7-bin.jar differ
diff --git a/extra/jheidi/lib/quaqua.jar b/extra/jheidi/lib/quaqua.jar
new file mode 100644
index 00000000..4ea991a0
Binary files /dev/null and b/extra/jheidi/lib/quaqua.jar differ
diff --git a/extra/jheidi/loadDatabaseInfo.ajl b/extra/jheidi/loadDatabaseInfo.ajl
new file mode 100644
index 00000000..4788ad18
--- /dev/null
+++ b/extra/jheidi/loadDatabaseInfo.ajl
@@ -0,0 +1,34 @@
+
+ WindowContext context = argObj("windowContext");
+
+ DB db = context.get("db");
+ DB.Result databases = db.execute("show table status from " + arg("dbName"));
+
+ Text banner = context.get("/mainTabs/Database/toolbar/banner");
+ banner.setText("Database " + arg("dbName") + ": " + databases.size() + " table(s)");
+
+ banner = context.get("/mainTabs/Query/toolbar/banner");
+ banner.setText("SQL query on database: " + arg("dbName"));
+
+ TableUtils.populate((Table)context.get("/mainTabs/Database/table"), databases);
+
+ //let the refresh button know what to do
+ Panel tab = context.get("/mainTabs/Database");
+ tab.setProperty("refreshScript", "loadDatabaseInfo");
+ tab.setProperty("refreshArgs", args());
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/loadHostInfo.ajl b/extra/jheidi/loadHostInfo.ajl
new file mode 100644
index 00000000..d3e955e2
--- /dev/null
+++ b/extra/jheidi/loadHostInfo.ajl
@@ -0,0 +1,39 @@
+
+ WindowContext context = argObj("windowContext");
+
+ DB db = context.get("db");
+
+ db.begin();
+ DB.Result version = db.query("select version()");
+ DB.Result vars = db.execute("show variables");
+ DB.Result processes = db.execute("show full processlist");
+ db.end();
+
+ Text banner = context.get("/mainTabs/Host/toolbar/banner");
+ banner.setText("MySQL " + version.first().get(0));
+ Table varTable = context.get("/mainTabs/Host/tabs/Variables/table");
+ TableUtils.populate(varTable, vars);
+ Table processTable = context.get("/mainTabs/Host/tabs/Processes/table");
+ TableUtils.populate(processTable, processes);
+
+ //let the refresh button know what to do
+ Panel tab = context.get("/mainTabs/Host");
+ tab.setProperty("refreshScript", "loadHostInfo");
+ tab.setProperty("refreshArgs", args());
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/loadTableData.ajl b/extra/jheidi/loadTableData.ajl
new file mode 100644
index 00000000..7bfba85f
--- /dev/null
+++ b/extra/jheidi/loadTableData.ajl
@@ -0,0 +1,43 @@
+
+ WindowContext context = argObj("windowContext");
+
+ DB db = context.get("db");
+
+ Table table = context.get("/mainTabs/Data/table");
+
+ db.begin();
+ db.execute("use " + arg("dbName"));
+ DB.Result count = db.query("select count(*) from " + arg("tableName"));
+ DB.Result data = db.query("select * from " + arg("tableName") + " limit 50");
+ db.end();
+
+ Text banner = context.get("/mainTabs/Data/toolbar/banner");
+ banner.setText(arg("dbName") + "." + arg("tableName") + ": " + count.first().get(0) + " total rows");
+
+ TableUtils.populate(table, data);
+
+ //let the refresh button know what to do
+ Panel tab = context.get("/mainTabs/Data");
+ tab.setProperty("refreshScript", "loadTableData");
+ tab.setProperty("refreshArgs", args());
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/loadTableInfo.ajl b/extra/jheidi/loadTableInfo.ajl
new file mode 100644
index 00000000..dc8b4c7f
--- /dev/null
+++ b/extra/jheidi/loadTableInfo.ajl
@@ -0,0 +1,35 @@
+
+ WindowContext context = argObj("windowContext");
+
+ DB db = context.get("db");
+
+ db.begin();
+ db.execute("use " + arg("dbName"));
+ DB.Result tables = db.execute("show full columns from " + arg("tableName"));
+ db.end();
+
+ Text banner = context.get("/mainTabs/Table/toolbar/banner");
+ banner.setText("Table properties for " + arg("dbName") + "." + arg("tableName") );
+
+ TableUtils.populate((Table)context.get("/mainTabs/Table/table"), tables);
+
+ //let the refresh button know what to do
+ Panel tab = context.get("/mainTabs/Table");
+ tab.setProperty("refreshScript", "loadTableInfo");
+ tab.setProperty("refreshArgs", args());
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/logs/log4jconfig.xml b/extra/jheidi/logs/log4jconfig.xml
new file mode 100755
index 00000000..8de3f355
--- /dev/null
+++ b/extra/jheidi/logs/log4jconfig.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/mainToolbarEvents.ajl b/extra/jheidi/mainToolbarEvents.ajl
new file mode 100644
index 00000000..ec306970
--- /dev/null
+++ b/extra/jheidi/mainToolbarEvents.ajl
@@ -0,0 +1,114 @@
+import javax.swing.tree.*;
+
+String who = arg("source");
+
+WindowContext context = argObj("windowContext");
+
+log.debug("Event received: " + who);
+
+if ("Connect".equals(who) )
+{
+ script("jheidi");
+}
+else if ("Refresh".equals(who))
+{
+
+ thread("initTree", args(), true);
+
+ Panel tab = (Panel)((Tabs)context.get("/mainTabs")).getSelectedComponent();
+ String script = tab.getProperty("refreshScript");
+ if ( script != null )
+ {
+ thread(script, (HashObject)tab.getProperty("refreshArgs"), true);
+ }
+
+}
+else if ("Cut".equals(who) || "Copy".equals(who) || "Paste".equals(who) )
+{
+ Editor editor = context.get("/mainTabs/Query/editor");
+ if ( editor.hasFocus() )
+ {
+ if ( "Cut".equals(who) )
+ {
+ editor.cut();
+ }
+ else if ("Copy".equals(who))
+ {
+ editor.copy();
+ }
+ else if ("Paste".equals(who))
+ {
+ editor.paste();
+ }
+ }
+}
+else if ("Drop Table".equals(who))
+{
+ Tree schemaTree = context.get("/schemaTree");
+ NodeInfo node = schemaTree.getSelectedNode();
+ if ( node != null && "table".equals(node.getType()) )
+ {
+ NodeInfo dbNode = node.getParent();
+ Frame f = context.get("/");
+ if (f.popupConfirm("Confirm Delete!", "Are you sure you want to drop table '" + dbNode.getText() + "." + node.getText() + "'?"))
+ {
+ args().put("tableToDrop", node.getText());
+ script("dropTable", args());
+ node.remove();
+ //force the tabs to refresh and the db info to reload
+ //schema tree events will be called by the tree itself
+ context.put("currentDB", null);
+ schemaTree.select(dbNode);
+ }
+ }
+
+}
+else if ("Create Database".equals(who))
+{
+ if ( script("createDBDialog", args()) != null )
+ {
+ Tree schemaTree = context.get("/schemaTree");
+ thread("initTree", args(), true);
+ }
+
+}
+else if ("Create Table".equals(who))
+{
+ if ( script("createTableDialog", args()) != null )
+ {
+ Tree schemaTree = context.get("/schemaTree");
+ thread("initTree", args(), true);
+ }
+
+}
+else if ("Drop Database".equals(who))
+{
+ Tree schemaTree = context.get("/schemaTree");
+ NodeInfo node = schemaTree.getSelectedNode();
+ NodeInfo root = node.getParent();
+ if ( node != null && "db".equals(node.getType()) )
+ {
+ Frame f = context.get("/");
+ if (f.popupConfirm("Confirm Delete!", "Are you sure you want to drop db '" + node.getText() + "'?"))
+ {
+ args().put("dbToDrop", node.getText());
+ DB db = context.get("db");
+ db.execute("drop database " + node.getText());
+ node.remove();
+ schemaTree.select(root);
+ }
+ }
+}
+else if ("Help".equals(who))
+{
+ BareBonesBrowserLaunch.openURL("http://www.heidisql.com");
+}
+else if ("Close".equals(who) )
+{
+ Frame window = context.get("/");
+ window.dispose();
+}
+else {
+ ((Frame)context.get("/")).popupMessage("Feature Unimplemented!");
+}
+
diff --git a/extra/jheidi/mainWindowEvents.ajl b/extra/jheidi/mainWindowEvents.ajl
new file mode 100644
index 00000000..892fcffe
--- /dev/null
+++ b/extra/jheidi/mainWindowEvents.ajl
@@ -0,0 +1,119 @@
+
+String who = arg("source");
+
+WindowContext context = argObj("windowContext");
+
+log.debug("Event received: " + who);
+
+if ("Close".equals(who) )
+{
+ Frame window = context.get("/");
+ window.dispose();
+}
+else if ("Connection".equals(who))
+{
+ script("jheidi");
+}
+else if ("Refresh".equals(who))
+{
+
+ thread("initTree", args(), true);
+
+ Panel tab = (Panel)((Tabs)context.get("/mainTabs")).getSelectedComponent();
+ String script = tab.getProperty("refreshScript");
+ if ( script != null )
+ {
+ thread(script, (HashObject)tab.getProperty("refreshArgs"), true);
+ }
+
+}
+//we may need a better way of doing this?
+else if ("Cut".equals(who) || "Copy".equals(who) || "Paste".equals(who) )
+{
+ Editor editor = context.get("/mainTabs/Query/editor");
+ log.debug("editor focus? " + editor.hasFocus());
+ if ( true /*for now editor.hasFocus()*/ )
+ {
+ if ( "Cut".equals(who) )
+ {
+ editor.cut();
+ }
+ else if ("Copy".equals(who))
+ {
+ editor.copy();
+ }
+ else if ("Paste".equals(who))
+ {
+ editor.paste();
+ }
+ }
+}
+else if ("Drop Table".equals(who))
+{
+ Tree schemaTree = context.get("/schemaTree");
+ NodeInfo node = schemaTree.getSelectedNode();
+ if ( node != null && "table".equals(node.getType()) )
+ {
+ NodeInfo dbNode = node.getParent();
+ Frame f = context.get("/");
+ if (f.popupConfirm("Confirm Delete!", "Are you sure you want to drop table '" + dbNode.getText() + "." + node.getText() + "'?"))
+ {
+ args().put("tableToDrop", node.getText());
+ script("dropTable", args());
+ node.remove();
+ //force the tabs to refresh and the db info to reload
+ //schema tree events will be called by the tree itself
+ context.put("currentDB", null);
+ schemaTree.select(dbNode);
+ }
+ }
+
+}
+else if ("Create Database".equals(who))
+{
+ if ( script("createDBDialog", args()) != null )
+ {
+ Tree schemaTree = context.get("/schemaTree");
+ thread("initTree", args(), true);
+ }
+
+}
+else if ("Create Table".equals(who))
+{
+ if ( script("createTableDialog", args()) != null )
+ {
+ Tree schemaTree = context.get("/schemaTree");
+ thread("initTree", args(), true);
+ }
+
+}
+else if ("Drop Database".equals(who))
+{
+ Tree schemaTree = context.get("/schemaTree");
+ NodeInfo node = schemaTree.getSelectedNode();
+ NodeInfo root = node.getParent();
+ if ( node != null && "db".equals(node.getType()) )
+ {
+ Frame f = context.get("/");
+ if (f.popupConfirm("Confirm Delete!", "Are you sure you want to drop db '" + node.getText() + "'?"))
+ {
+ args().put("dbToDrop", node.getText());
+ DB db = context.get("db");
+ db.execute("drop database " + node.getText());
+ node.remove();
+ schemaTree.select(root);
+ }
+ }
+}
+else if ("Heidi SQL Website".equals(who))
+{
+ BareBonesBrowserLaunch.openURL("http://www.heidisql.com");
+}
+else if ( "Exit".equals(who) )
+{
+ System.exit(0);
+}
+else {
+ ((Frame)context.get("/")).popupMessage("Feature Unimplemented!");
+}
+
diff --git a/extra/jheidi/queryToolbarEvents.ajl b/extra/jheidi/queryToolbarEvents.ajl
new file mode 100644
index 00000000..a7659f46
--- /dev/null
+++ b/extra/jheidi/queryToolbarEvents.ajl
@@ -0,0 +1,85 @@
+
+String who = arg("source");
+
+WindowContext context = argObj("windowContext");
+Editor editor = context.get("/mainTabs/Query/editor");
+
+log.debug("Event received: " + who);
+
+if ("Run".equals(who) || "Run Selection".equals(who) )
+{
+ String editorText = who.startsWith("Run S") ? editor.getSelectedText() : editor.getText();
+ if ( editorText != null )
+ {
+ StringBuilder query = new StringBuilder(1000);
+ HashObject queries = new HashObject();
+ String[] lines = StringUtils.toLines( editorText, true );
+
+ log.debug("lines in query window: " + lines.length);
+
+ for ( String line: lines )
+ {
+ if ( line.length() == 0 || line.startsWith("--") || line.startsWith("//") )
+ {
+ continue;
+ }
+ else
+ {
+ query.append(line).append("\n");
+ }
+ if ( line.endsWith(";") )
+ {
+ String userQuery = query.toString();
+ if ( userQuery.length() > 0 )
+ {
+ log.debug("line terminated query: " + userQuery);
+ queries.add(userQuery);
+ }
+ query.delete(0, query.length());
+ }
+ }
+ String userQuery = query.toString();
+ if ( userQuery.length() > 0 )
+ {
+ log.debug("non-terminated query: *" + query.toString() + "*");
+ queries.add(userQuery);
+ }
+ if ( queries.size() > 0 )
+ {
+ args().put("userQueries", queries);
+ thread("runUserQueries", args(), true);
+ }
+ }
+}
+else if ("Open Script".equals(who))
+{
+ Frame f = context.get("/");
+ String file = f.openFile(null, "SQL Script Files", "sql");
+ if (file != null)
+ {
+ editor.setText(FileUtil.toString(file));
+ editor.setProperty("filePath", file);
+ }
+}
+else if ("Save".equals(who) || "Save As".equals(who))
+{
+ Frame f = context.get("/");
+ if ( editor.getProperty("filePath") != null && "Save".equals(who))
+ {
+ FileUtil.fromString((String)editor.getProperty("filePath"), editor.getText());
+ }
+ else
+ {
+ String file = f.saveFile(null, "SQL Script Files", "sql");
+ if (file != null)
+ {
+ FileUtil.fromString(file, editor.getText());
+ editor.setProperty("filePath", file);
+ }
+ }
+}
+else if ("Clear".equals(who))
+{
+ editor.setText("");
+}
+
diff --git a/extra/jheidi/readme-or it wont work.txt b/extra/jheidi/readme-or it wont work.txt
new file mode 100644
index 00000000..b29c9450
--- /dev/null
+++ b/extra/jheidi/readme-or it wont work.txt
@@ -0,0 +1,26 @@
+
+This readme applies to the src distro of jHeidi ONLY.
+If you are not modifying the app pls download the binary distro.
+
+Define JAVA_HOME to point to the root of your JDK installation.
+
+It is not legal to ship tools.jar separately from the JDK so setting JAVA_HOME allows the
+script compiler to work.
+
+Once this is done, you may make modifications to scripts in the root dir named *.ajl
+restart the application and your changes will be seen.
+
+run the application using the following command.
+
+ajl jheidi.
+
+There is an option to use an automatic class reloader so you dont have to restart the application
+to see your changes however it is not guaranteed to work in this alpha release
+as it has not been fully tested with this application. The next release should support it.
+
+Java 1.6 is recommended but Java 1.5 should work. Please dont develop on old JDKs.
+
+This application and all associated non-third party code is in the public domain
+and copyright laws are not applicable.
+
+
diff --git a/extra/jheidi/resetTabs.ajl b/extra/jheidi/resetTabs.ajl
new file mode 100644
index 00000000..ce147245
--- /dev/null
+++ b/extra/jheidi/resetTabs.ajl
@@ -0,0 +1,39 @@
+ import javax.swing.table.*;
+
+ WindowContext context = argObj("windowContext");
+ HashObject profile = context.get("profile");
+
+ Text banner = null;
+ Table table = null;
+
+ if ( "Host".equals(arg("selectedTab")) )
+ {
+ banner = context.get("/mainTabs/Database/toolbar/banner");
+ banner.setText("No database selected");
+ table = context.get("/mainTabs/Database/table");
+ table.clear();
+ banner = context.get("/mainTabs/Query/toolbar/banner");
+ banner.setText("SQL query on " + profile.get("user") + "@" + profile.get("host"));
+ }
+ else
+ {
+ banner = context.get("/mainTabs/Query/toolbar/banner");
+ banner.setText("SQL query on database: " + context.get("currentDB"));
+ }
+
+ banner = context.get("/mainTabs/Table/toolbar/banner");
+ banner.setText("No table selected");
+ table = context.get("/mainTabs/Table/table");
+ table.clear();
+ banner = context.get("/mainTabs/Data/toolbar/banner");
+ banner.setText("No table selected");
+ table = context.get("/mainTabs/Data/table");
+ table.clear();
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/runUserQueries.ajl b/extra/jheidi/runUserQueries.ajl
new file mode 100644
index 00000000..a8849b04
--- /dev/null
+++ b/extra/jheidi/runUserQueries.ajl
@@ -0,0 +1,31 @@
+import java.util.*;
+
+HashObject userQueries = argObj("userQueries");
+WindowContext context = argObj("windowContext");
+
+DB.Result results = null;
+DB db = context.get("db");
+db.begin();
+if (context.get("currentDB") != null)
+{
+ db.execute("use " + context.get("currentDB"));
+}
+db.setLimit(1000);
+for (String userQuery : (List)userQueries)
+{
+ try {
+ results = db.execute(userQuery);
+ }
+ catch (Exception e)
+ {
+ log.error("",e);
+ }
+}
+db.setLimit(-1);
+db.end();
+
+//if the last statement didnt have any results oh well!
+Table t = context.get("/mainTabs/Query/results");
+TableUtils.populate(t, results);
+
+
diff --git a/extra/jheidi/schemaTreeEvents.ajl b/extra/jheidi/schemaTreeEvents.ajl
new file mode 100644
index 00000000..db3740cf
--- /dev/null
+++ b/extra/jheidi/schemaTreeEvents.ajl
@@ -0,0 +1,77 @@
+
+ NodeInfo node = argObj("node");
+ WindowContext context = argObj("windowContext");
+
+ Tabs tabs = context.get("/mainTabs");
+ String selectedTab = tabs.selected();
+ String nodeType = node.getType();
+
+ log.debug("node type = " + nodeType);
+ log.debug("selected tab = " + selectedTab);
+
+ if ( nodeType == null )
+ {
+ tabs.select("Host");
+ args().put("selectedTab", "Host");
+ thread("resetTabs", args(), true);
+ }
+ else if ( "db".equals(nodeType) )
+ {
+ String dbName = node.getText();
+ Panel tab = tabs.select("Database");
+ if ( !dbName.equals(context.get("currentDB")) )
+ {
+ context.put("currentDB", dbName);
+ context.remove("currentTable");
+ args().put("selectedTab", "Database");
+ thread("resetTabs", args(), true);
+ args().put("dbName", dbName);
+ thread("loadDatabaseInfo", args(), true);
+ }
+ }
+ else if ( "table".equals(nodeType) )
+ {
+ String dbName = node.getParent().getText();
+ String tableName = node.getText();
+
+ Panel tab = tabs.get("Table");
+ if ("Host".equals(selectedTab) || "Database".equals(selectedTab))
+ {
+ tabs.select("Table");
+ }
+
+ if (!dbName.equals(context.get("currentDB")))
+ {
+ context.put("currentDB", dbName);
+ args().put("dbName", dbName);
+ thread("loadDatabaseInfo", args(), true);
+ }
+
+ if ( !tableName.equals(context.get("currentTable")) || !dbName.equals(context.get("currentDB")) )
+ {
+ context.put("currentTable", node.getText());
+ args().put("dbName", dbName);
+ args().put("tableName", tableName);
+ thread("loadTableInfo", args(), true);
+ thread("loadTableData", args(), true);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extra/jheidi/showMainWindow.ajl b/extra/jheidi/showMainWindow.ajl
new file mode 100644
index 00000000..a65ae733
--- /dev/null
+++ b/extra/jheidi/showMainWindow.ajl
@@ -0,0 +1,125 @@
+ import com.rendion.editor.*;
+
+ HashObject profile = argObj("profile");
+
+ Frame app = new Frame("mainWindow", "JHeidi [" + profile.get("name") + " - " + profile.get("user") + "@" + profile.get("host") + "]");
+ WindowContext context = app.getWindowContext();
+ context.put("profile", profile);
+
+ app.events("mainWindowEvents");
+
+ app.toolbarButtonInsets(100, 100, 100, 100);
+
+ //set up the menus
+ app.menu("&File").item("Connection", "Close", "separator", "Reset Window-Options", "Export Settings...", "Import Settings...", "separator", "Exit");
+ app.menu("&Edit").item("Cut", "Copy", "Paste");
+ Menu m = app.menu("&Tools").item("Refresh", "separator", "Create Database", "Drop Database", "Create Table", "Drop Table" , "separator");
+ Menu flush = m.submenu("Flush");
+ flush.item("Hosts", "Logs", "Privledges", "Tables", "Tables with Read Lock", "Status" );
+ m.item("separator", "User-Manager", "Maintenance", "separator", "Preferences");
+ app.menu("&Import").item("Import CSV File", "Load SQL File", "Insert Files into Blob Fields");
+ app.menu("E&xport").item("Export Tables as SQL","separator", "Copy as CSV Data", "Copy as HTML Data", "Copy as XML Data","Export Data...");
+ app.menu("&Window").item("Connection 1");
+ app.menu("&Help").item("SQL Help", "separator", "Heidi SQL Website", "Download Page", "Support Forum", "Bug Tracker", "Feature Tracker",
+ "separator", "About");
+
+ app.toolbar("mainToolbar").events("mainToolbarEvents")
+ .button("Connect", "images/connect.gif")
+ .button("Close", "images/disconnect.gif")
+ .separator()
+ .button("Cut", "images/cut.gif")
+ .button("Copy", "images/copy.gif")
+ .button("Paste", "images/paste.gif")
+ .button("Print", "images/print.gif")
+ .separator()
+ .button("Create Database", "images/db-center.gif")
+ .button("Drop Database", "images/deletedb.gif")
+ .button("Create Table", "images/table.gif")
+ .button("Drop Table", "images/deletetable.gif")
+ .separator()
+ .button("Refresh", "images/refresh.gif")
+ .separator()
+ .button("Import", "images/import.gif")
+ .button("Export", "images/export.gif")
+ .separator()
+ .button("Help", "images/help.gif");
+
+ app.statusBar("statusBar", "Ready");
+
+ //set up the splitters and tabs
+ Split mainSplit = app.splitVertical("treeTabsOutput", 640);
+ mainSplit
+ .splitHorizontal("splitSchemaQuery", 300)
+ .tree("schemaTree")
+ .tabs("mainTabs");
+
+ Tree schemaTree = app.get("schemaTree");
+ schemaTree.events("schemaTreeEvents");
+
+ Tabs consoleTabs = mainSplit.tabs("consoleTabs");
+ Panel consoleTab = consoleTabs.tab("SQL Log", LF.isWin? "images/vista/sqllog.gif" : "images/sqllog.gif")
+ .editor("outputWindow");
+
+ Tabs tabs = app.get("mainTabs");
+ Panel host = tabs.tab("Host", LF.isWin? "images/vista/instance.gif" : "images/instance.gif");
+ host.toolbar("toolbar", 32)
+ .text("banner", "MySQL version etc")
+ .horizontalGlue();
+
+ Tabs hostTabs = host.tabs("tabs");
+ hostTabs.tab("Variables").table("table", new String[] {"\t"}, new String[][] {{""}});
+ hostTabs.tab("Processes").table("table", new String[] {"\t"}, new String[][] {{""}});
+
+ Panel dbTab = tabs.tab("Database", "images/db-center.gif");
+ dbTab.toolbar("toolbar", 32)
+ .text("banner", "No database selected")
+ .horizontalGlue();
+ dbTab.table("table", new String[] {"\t"}, new String[][] {{""}});
+
+ Panel tableTab = tabs.tab("Table", "images/table.gif");
+ tableTab.toolbar("toolbar", 32).events("tableToolbarEvents")
+ .text("banner", "No table selected")
+ .horizontalGlue()
+ .button("New Field", "images/newfield.gif")
+ .button("Edit Field", "images/editfield.gif")
+ .button("Delete Field", "images/deletefield.gif")
+ .button("Manage Indexes", "images/manageindexes.gif");
+ tableTab.table("table", new String[] {"\t"}, new String[][] {{""}});
+
+ Panel dataTab = tabs.tab("Data", "images/data.gif");
+ dataTab.toolbar("toolbar", 32)
+ .text("banner", "No table selected")
+ .horizontalGlue();
+ dataTab.table("table", new String[] {"\t"}, new String[][] {{""}});
+
+ Panel queryTab = tabs.tab("Query", "images/query.gif");
+ queryTab.toolbar("toolbar").events("queryToolbarEvents")
+ .text("banner", "SQL query for " + profile.get("user") + "@" + profile.get("host"))
+ .horizontalGlue()
+ .button("Run", "images/run.gif")
+ .button("Run Selection", "images/runselection.gif")
+ .button("Stop", "images/stop.gif")
+ .separator()
+ .button("Search", "images/search.gif")
+ .button("Clear", "images/clear.gif")
+ .separator()
+ .button("Open Script", "images/folder.gif")
+ .button("Save", "images/save.gif")
+ .button("Save As", "images/saveas.gif");
+
+ queryTab.splitVertical("queryResults", 180)
+ .editor("editor")
+ .table("results", new String[] {"\t"}, new String[][] {{""}});
+
+ AjlEditor editor = consoleTab.get("outputWindow");
+ editor.setEditable(false);
+
+ app.maximize();
+ app.visible();
+
+ args().put("windowContext", context);
+ script("initDB", args());
+ script("initTree", args());
+ thread("loadHostInfo", args(), true);
+
+
diff --git a/extra/jheidi/tableToolbarEvents.ajl b/extra/jheidi/tableToolbarEvents.ajl
new file mode 100644
index 00000000..4b485898
--- /dev/null
+++ b/extra/jheidi/tableToolbarEvents.ajl
@@ -0,0 +1,73 @@
+
+String who = arg("source");
+
+WindowContext context = argObj("windowContext");
+Table table = context.get("/mainTabs/Table/table");
+boolean refreshTableTab = false;
+
+log.debug("Event received: " + who);
+
+if ( context.get("currentTable") == null )
+{
+ return;
+}
+
+if ("Delete Field".equals(who) )
+{
+ if ( table.getSelectedRow() != -1 )
+ {
+ Frame frame = context.get("/");
+ String tableName = context.get("currentTable");
+ String fieldName = (String)table.getValueAt(table.getSelectedRow(), 0);
+ if (frame.popupConfirm("Confirm Delete!", "Are you sure you want to drop field '" + tableName + "." + fieldName + "'?"))
+ {
+ args().put("fieldToDrop", fieldName);
+ script("dropField", args());
+ refreshTableTab = true;
+ }
+ }
+
+}
+else if ("New Field".equals(who))
+{
+ args().put("fieldMode", "Add");
+ if ( script("fieldDialog", args()) != null )
+ {
+ refreshTableTab = true;
+ }
+
+}
+else if ("Edit Field".equals(who))
+{
+ if ( table.getSelectedRow() != -1 )
+ {
+ String fieldName = (String)table.getValueAt(table.getSelectedRow(), 0);
+ args().put("fieldMode", "Edit");
+ args().put("fieldToEdit", fieldName);
+ if ( script("fieldDialog", args()) != null )
+ {
+ refreshTableTab = true;
+ }
+ }
+}
+else if ("Manage Indexes".equals(who))
+{
+ if ( script("indexDialog", args()) != null )
+ {
+ refreshTableTab = true;
+ }
+}
+else
+{
+ ((Frame)context.get("/")).popupMessage("Feature Unimplemented!");
+}
+
+
+if ( refreshTableTab )
+{
+ Panel tab = context.get("/mainTabs/Table");
+ String script = tab.getProperty("refreshScript");
+ thread(script, (HashObject)tab.getProperty("refreshArgs"), true);
+}
+
+
diff --git a/extra/jheidi/testConnect.ajl b/extra/jheidi/testConnect.ajl
new file mode 100644
index 00000000..4d6edba6
--- /dev/null
+++ b/extra/jheidi/testConnect.ajl
@@ -0,0 +1,28 @@
+import com.mysql.jdbc.jdbc2.optional.*;
+import javax.sql.DataSource;
+
+DB db = null;
+
+WindowContext context = argObj("windowContext");
+Frame f = context.get("/");
+HashObject profile = argObj("profile");
+
+try
+{
+ MysqlDataSource ds = new MysqlDataSource();
+ String url = "jdbc:mysql://" + profile.get("host") + ":" + profile.get("port") + "/";
+
+ ds.setUrl(url);
+ ds.setUser(profile.get("user"));
+ ds.setPassword(profile.get("password"));
+
+ db = new DB((DataSource)ds);
+ db.execute("select 'abcdefg'");
+
+} catch (Exception e) {
+ f.popupMessage("Connection Failed!", e.getCause().toString());
+ db = null;
+}
+
+return db;
+
diff --git a/extra/jheidi/typeChangeEvents.ajl b/extra/jheidi/typeChangeEvents.ajl
new file mode 100644
index 00000000..7fb5293a
--- /dev/null
+++ b/extra/jheidi/typeChangeEvents.ajl
@@ -0,0 +1,81 @@
+ import javax.swing.*;
+ import java.awt.*;
+
+ WindowContext context = argObj("windowContext");
+
+ Combo combo = context.get("/types");
+ String selection = combo.getText();
+ log.debug("selection is: " + selection);
+
+ HashObject defSizeMap = combo.getProperty("defSizeMap");
+ HashObject typeMap = combo.getProperty("typeStateMap");
+ Object[] widgets = combo.getProperty("widgets");
+
+ int[] currentState = combo.getProperty("currentCheckState");
+ int[] typeState = (int[])typeMap.getObject(selection);
+
+ log.debug("currentState: " + currentState);
+
+ /*((JCheckBox)context.get("/primary")).setSelected(false);
+ ((JCheckBox)context.get("/index")).setSelected(false);
+ ((JCheckBox)context.get("/unique")).setSelected(false);
+ ((JCheckBox)context.get("/notNull")).setSelected(false);
+ ((JCheckBox)context.get("/autoInc")).setSelected(false);*/
+
+ for ( int i = 0; i < widgets.length; i++ )
+ {
+ if ( currentState == null || (currentState[i] != typeState[i]) )
+ {
+ boolean enabled = typeState[i] >0;
+ boolean selected = typeState[i] == 2;
+
+ ((JComponent)widgets[i]).setEnabled(enabled);
+
+ if ( widgets[i] instanceof JCheckBox )
+ {
+ ((JCheckBox)widgets[i]).setSelected(selected);
+ ((JCheckBox)widgets[i]).updateUI();
+ }
+ else if ( widgets[i] instanceof Field )
+ {
+ String value = "";
+ if ( i == 3 )
+ {
+ value = defSizeMap.get(selection) == null ? "" :
+ defSizeMap.get(selection);
+ Text t = context.get("/Length/Set:");
+ t.style(selected? Font.BOLD : Font.PLAIN);
+
+ }
+ ((Field)widgets[i]).setText(value);
+ }
+
+
+
+ }
+ //ucommented for now this just confuses things
+ // combo.setProperty("currentCheckState", typeState);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+