initial quantum version
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / view / SQLQueryView.java
diff --git a/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/view/SQLQueryView.java b/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/view/SQLQueryView.java
new file mode 100644 (file)
index 0000000..a8469e7
--- /dev/null
@@ -0,0 +1,517 @@
+package com.quantum.view;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ExtendedModifyEvent;
+import org.eclipse.swt.custom.ExtendedModifyListener;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.part.ViewPart;
+
+import com.quantum.Messages;
+import com.quantum.QuantumPlugin;
+import com.quantum.actions.ExecuteAction;
+import com.quantum.actions.ExportQueryAction;
+import com.quantum.actions.ImportQueryAction;
+import com.quantum.model.Bookmark;
+import com.quantum.model.NotConnectedException;
+import com.quantum.sql.MultiSQLServer;
+import com.quantum.sql.parser.SQLLexx;
+import com.quantum.sql.parser.Token;
+import com.quantum.view.bookmark.BookmarkNode;
+import com.quantum.view.bookmark.BookmarkView;
+
+public class SQLQueryView extends ViewPart {
+       private ExecuteAction executeAction;
+       private ImportQueryAction importQueryAction;
+       private ExportQueryAction exportQueryAction;
+       private Label statusImage;
+       private Label status;
+       private ProgressBar progress;
+       private StyledText widget;
+       private ToolItem autoCommitItem;
+       private ToolItem commitItem;
+       private ToolItem rollbackItem;
+       private Color STRING_LITERAL;
+       private Color KEYWORD;
+       private Color COMMENT;
+       private Color NUMERIC;
+       private Color DEFAULT;
+       private long parseTime = 0;
+       private long fullTime = 0;
+       public SQLQueryView() {
+               super();
+       }
+       public void setFocus() {
+               
+               String title = "Quantum SQL Query Editor";
+               BookmarkNode bookmarkNode = null;
+               Bookmark bookmark = null;
+               Connection con = null;
+               if (BookmarkView.getInstance() != null ) {
+                       bookmarkNode = BookmarkView.getInstance().getCurrentBookmark();
+               }
+               if (bookmarkNode != null)
+                       bookmark = bookmarkNode.getBookmark();
+               if (bookmark != null) {         
+                       title = bookmark.getName() + " (" + title + ")";
+                       setTitle( title );
+                       try {
+                               con = bookmark.getConnection();
+                       } catch (NotConnectedException e) {
+                               // Doesn't matter, "con" remains null
+                       }
+               }
+               
+               updateAutoCommitState(bookmark, con);
+
+               widget.setFocus();
+
+       }
+       public static SQLQueryView getInstance() {
+               return (SQLQueryView) QuantumPlugin.getDefault().getView("com.quantum.view.sqlqueryview");
+
+       }
+
+       public void createPartControl(org.eclipse.swt.widgets.Composite parent) {
+               initActions();
+               KEYWORD = new Color(parent.getShell().getDisplay(), 126, 0, 75);
+               STRING_LITERAL = new Color(parent.getShell().getDisplay(), 0, 0, 255);
+               COMMENT = new Color(parent.getShell().getDisplay(), 88, 148, 64);
+               NUMERIC = new Color(parent.getShell().getDisplay(), 255, 0, 0);
+           DEFAULT = new Color(parent.getShell().getDisplay(), 0, 0, 0);
+               Composite main = new Composite(parent, SWT.NONE);
+               GridLayout layout = new GridLayout(1, false);
+               layout.horizontalSpacing = 0;
+               layout.verticalSpacing = 0;
+               main.setLayout(layout);
+               ToolBar toolbar = new ToolBar(main, SWT.HORIZONTAL);
+               ToolItem item = new ToolItem(toolbar, SWT.PUSH);
+               item.setImage(QuantumPlugin.getImage("play.gif")); //$NON-NLS-1$
+               item.setToolTipText(Messages.getString("sqlqueryview.executeQuery")); //$NON-NLS-1$
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               executeAction.run();
+                       }
+               });
+               item = new ToolItem(toolbar, SWT.SEPARATOR);
+               item = new ToolItem(toolbar, SWT.PUSH);
+               item.setImage(QuantumPlugin.getImage("import.gif")); //$NON-NLS-1$
+               item.setToolTipText(Messages.getString("sqlqueryview.importQuery")); //$NON-NLS-1$
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               importQueryAction.run();
+                       }
+               });
+               item = new ToolItem(toolbar, SWT.PUSH);
+               item.setImage(QuantumPlugin.getImage("export.gif")); //$NON-NLS-1$
+               item.setToolTipText(Messages.getString("sqlqueryview.exportQuery")); //$NON-NLS-1$
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               exportQueryAction.run();
+                       }
+               });
+               item = new ToolItem(toolbar, SWT.PUSH);
+               item.setImage(QuantumPlugin.getImage("clear.gif")); //$NON-NLS-1$
+               item.setToolTipText(Messages.getString("sqlqueryview.clear")); //$NON-NLS-1$
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               setQuery(""); //$NON-NLS-1$
+                       }
+               });
+
+               item = new ToolItem(toolbar, SWT.SEPARATOR);
+
+               commitItem = new ToolItem(toolbar, SWT.PUSH);
+               commitItem.setImage(QuantumPlugin.getImage("commit.gif")); //$NON-NLS-1$
+               commitItem.setToolTipText(Messages.getString("SQLQueryView.Commit")); //$NON-NLS-1$
+               commitItem.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent event) {
+                try {
+                               BookmarkNode node = BookmarkView.getInstance().getCurrentBookmark();
+                               if (node != null) MultiSQLServer.getInstance().commit(
+                        node.getBookmark().getConnection());
+                } catch (NotConnectedException e) {
+                    e.printStackTrace();
+                }
+                       }
+               });
+               
+               rollbackItem = new ToolItem(toolbar, SWT.PUSH);
+               rollbackItem.setImage(QuantumPlugin.getImage("rollback.gif")); //$NON-NLS-1$
+               rollbackItem.setToolTipText(Messages.getString("SQLQueryView.RollBack")); //$NON-NLS-1$
+               rollbackItem.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent event) {
+                       }
+                       public void widgetSelected(SelectionEvent event) {
+                try {
+                    BookmarkNode node = BookmarkView.getInstance().getCurrentBookmark();
+                    if (node != null) MultiSQLServer.getInstance().rollback(
+                        node.getBookmark().getConnection());
+                } catch (NotConnectedException e) {
+                    e.printStackTrace();
+                }
+                       }
+               });
+               
+               autoCommitItem = new ToolItem(toolbar, SWT.CHECK);
+               autoCommitItem.setImage(QuantumPlugin.getImage("autocommit.gif")); //$NON-NLS-1$
+               autoCommitItem.setToolTipText(Messages.getString("SQLQueryView.AutoCommit")); //$NON-NLS-1$
+               autoCommitItem.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent event) {
+                               BookmarkNode node = BookmarkView.getInstance().getCurrentBookmark();
+                               if (node == null) return;
+                               Connection con = null; 
+                               try { 
+                                       // Get the connection
+                                       con = node.getBookmark().getConnection();
+                                       // If connected (else will throw exception and jump out) switchs the state of the
+                                       // autoCommit option of the JDBC driver
+                                       MultiSQLServer.getInstance().setAutoCommit(     con, autoCommitItem.getSelection());
+                } catch (NotConnectedException e) {
+                       //Doesn't matter
+                }
+                // Update the bookmark and the buttons
+                               updateAutoCommitState(node.getBookmark(), con);
+                               
+                       }
+               });
+               BookmarkNode node = BookmarkView.getInstance().getCurrentBookmark();
+               if (node == null) autoCommitItem.setSelection(true); 
+               else autoCommitItem.setSelection(node.getBookmark().isAutoCommit());
+               if (autoCommitItem.getSelection()) {
+                       commitItem.setEnabled(false);
+                       rollbackItem.setEnabled(false);
+               } else {
+                       commitItem.setEnabled(true);
+                       rollbackItem.setEnabled(true);
+               }
+               widget = new StyledText(main, SWT.H_SCROLL | SWT.V_SCROLL);
+
+               IActionBars bars = this.getViewSite().getActionBars();
+               bars.setGlobalActionHandler(IWorkbenchActionConstants.CUT, cutAction);
+               bars.setGlobalActionHandler(IWorkbenchActionConstants.COPY, copyAction);
+               bars.setGlobalActionHandler(IWorkbenchActionConstants.PASTE, pasteAction);
+               bars.setGlobalActionHandler(IWorkbenchActionConstants.SELECT_ALL, selectAllAction);
+
+               widget.setEditable(true);
+               widget.addExtendedModifyListener(modifyListener);
+
+               GridData gridData = new GridData();
+               gridData.horizontalAlignment = GridData.FILL;
+               gridData.verticalAlignment = GridData.FILL;
+               gridData.grabExcessHorizontalSpace = true;
+               gridData.grabExcessVerticalSpace = true;
+               widget.setLayoutData(gridData);
+
+               Composite bottomStatus = new Composite(main, SWT.NONE);
+               gridData = new GridData();
+               gridData.horizontalAlignment = GridData.FILL;
+               gridData.grabExcessHorizontalSpace = true;
+               bottomStatus.setLayoutData(gridData);
+               
+               GridLayout horizontal = new GridLayout(3, false);
+               layout.horizontalSpacing = 0;
+               layout.verticalSpacing = 0;
+               layout.marginHeight = 0;
+               layout.marginWidth = 0;
+               bottomStatus.setLayout(horizontal);
+
+               statusImage = new Label(bottomStatus, SWT.NONE);
+               status = new Label(bottomStatus, SWT.NONE);
+               gridData = new GridData();
+               gridData.horizontalAlignment = GridData.FILL;
+               gridData.grabExcessHorizontalSpace = true;
+               status.setLayoutData(gridData);
+
+               progress = new ProgressBar(bottomStatus, SWT.HORIZONTAL);
+
+               status.setText(Messages.getString("sqlqueryview.done")); //$NON-NLS-1$
+               statusImage.setImage(QuantumPlugin.getImage("success.gif")); //$NON-NLS-1$
+               progress.setMinimum(0);
+        
+        IKeyBindingService keyBindingService = getSite().getKeyBindingService();
+        // TODO: check the version numbers for this method
+        keyBindingService.setScopes(new String[] {
+            "org.eclipse.ui.globalScope",
+            "com.quantum.view.sql"
+        });
+        keyBindingService.registerAction(this.executeAction);
+       }
+
+       /**
+        * Sets the state of the "Commit", "Rollback" and "autoCommit" buttons
+        * to reflect the situation in the connection
+        */
+       protected void updateAutoCommitState(Bookmark bookmark, Connection con) {
+               boolean autoCommit = true;
+               // Calculate the state of the autoCommit option
+               if (con != null)
+               {
+                       // If we have a connection, the autoCommit state is that of the connection
+                       try {
+                               autoCommit = con.getAutoCommit();
+                       } catch (SQLException e) {
+                               // Doesn't matter, we take default
+                       }
+               } else {
+                       // if no connection, we try the autoCommit of the bookmark, or else the default
+                       if (bookmark != null) autoCommit = bookmark.isAutoCommit();
+               }
+               // Set the autoCommit state of the bookmark to the calculated
+               if (bookmark != null) bookmark.setAutoCommit(autoCommit);
+               // Set the state of the buttons to the correct autoCommit state
+               autoCommitItem.setSelection(autoCommit);
+               if (autoCommitItem.getSelection()) {
+                       commitItem.setEnabled(false);
+                       rollbackItem.setEnabled(false);
+               } else {
+                       commitItem.setEnabled(true);
+                       rollbackItem.setEnabled(true);
+               }
+       }
+       public void setProgress(int increment, int max) {
+               progress.setMaximum(max);
+               progress.setSelection(increment);
+       }
+       
+       private void initActions() {
+               executeAction = new ExecuteAction();
+               executeAction.init(this);
+               importQueryAction = new ImportQueryAction();
+               importQueryAction.init(this);
+               exportQueryAction = new ExportQueryAction();
+               exportQueryAction.init(this);
+       }
+
+       public void setStatus(String text) {
+               statusImage.setImage(null);
+               status.setText(text);
+       }
+
+       public void setStatus(Image img, String text) {
+               statusImage.setImage(img);
+               status.setText(text);
+       }
+       
+       public String getQuery() {
+               return widget.getText();
+       }
+       
+       public void setQuery(String text) {
+               widget.setText(text);
+       }
+       
+       private String[] keywords = {
+       "ADD", "ALL", "ALTER", "AND", "ANY",
+       "AS", "ASC", "AUTOINCREMENT", "AVA", "BETWEEN",
+       "BINARY", "BIT", "BOOLEAN", "BY", "CREATE",
+       "BYTE", "CHAR", "CHARACTER", "COLUMN", "CONSTRAINT",
+       "COUNT", "COUNTER", "CURRENCY", "DATABASE", "DATE",
+       "DATETIME", "DELETE", "DESC", "DISALLOW", "DISTINCT",
+       "DISTINCTROW", "DOUBLE", "DROP", "EXISTS", "FROM",
+       "FLOAT", "FLOAT4", "FLOAT8", "FOREIGN", "GENERAL",
+       "GROUP", "GUID", "HAVING", "INNER", "INSERT",
+       "IGNORE", "IMP", "IN", "INDEX", "INT", 
+       "INTEGER", "INTEGER1", "INTEGER2", "INTEGER4", "INTO",
+       "IS", "JOIN", "KEY", "LEFT", "LEVEL", 
+       "LIKE", "LOGICAL", "LONG", "LONGBINARY", "LONGTEXT",
+       "MAX", "MEMO", "MIN", "MOD", "MONEY", 
+       "NOT", "NULL", "NUMBER", "NUMERIC", "OLEOBJECT",
+       "ON", "PIVOT", "OPTION", "PRIMARY", "ORDER",
+       "OUTER", "OWNERACCESS", "PARAMETERS", "PERCENT", "REAL",
+       "REFERENCES", "RIGHT", "SELECT", "SET", "SHORT",
+       "SINGLE", "SMALLINT", "SOME", "STDEV", "STDEVP",
+       "STRING", "SUM", "TABLE", "TABLEID", "TEXT", 
+       "TIME", "TIMESTAMP", "TOP", "TRANSFORM", "UNION",
+       "UNIQUE", "UPDATE", "VALUE", "VALUES", "VAR",
+       "VARBINARY", "VARCHAR", "VARP", "WHERE", "WITH",
+       "YESNO" };
+       
+       SyntaxHighlighter textUpdater = new SyntaxHighlighter();
+       
+       private class UpdateRequest {
+               public UpdateRequest(String text, int start, int length) {
+                       this.text = text;
+                       this.start = start;
+                       this.length = length;
+               }
+               public String text;
+               public int start;
+               public int length;
+       }
+       
+       private class SyntaxHighlighter extends Thread {
+               private boolean running = true;
+               private LinkedList requests = new LinkedList();
+               public SyntaxHighlighter() {
+                       super();
+                       setPriority(Thread.MIN_PRIORITY);
+                       start();
+               }
+               public synchronized void updateText(String text, int start, int length) {
+                       requests.add(new UpdateRequest(text, start, length));
+                       notify();
+               }
+               public synchronized void shutdown() {
+                       running = false;
+                       interrupt();
+               }
+               public void run() {
+                       while (running) {
+                               try {
+                                       synchronized (this) {
+                                               if (requests.size() <= 0) {
+                                                       wait();
+                                               } else {
+                                                       Thread.sleep(10);
+                                               }
+                                       }
+                                       UpdateRequest request = (UpdateRequest) requests.removeFirst();
+                                       String text = request.text.toUpperCase();
+                                       //int dirtyStart = request.start;
+                                       //int dirtyEnd = request.start + request.length;
+                                       StyleRange styleRange;
+                                       long startTime = System.currentTimeMillis();
+                                       Vector tokens = SQLLexx.parse(text);
+                                       long subTime = System.currentTimeMillis();
+                                       Vector styles = new Vector();
+                                       int min = Integer.MAX_VALUE;
+                                       int max = 0;
+                                       for (int i = 0; i < tokens.size(); i++) {
+                                               Token t = (Token) tokens.elementAt(i);
+                                               String value = t.getValue();
+                                               int start = t.getStart();
+                                               int length = t.getEnd() - t.getStart();
+                                               styleRange = new StyleRange();
+                                               styleRange.start = start;
+                                               styleRange.length = value.length();
+                                               styleRange.fontStyle = SWT.NULL;
+                                               styleRange.foreground = DEFAULT;
+                                               //boolean upper = start <= dirtyEnd && start >= dirtyStart;
+                                               //boolean lower = ((start + length) >= dirtyStart && (start + length) <= dirtyEnd);
+                                               //boolean both = (start <= dirtyStart && (start + length) >= dirtyEnd);
+                                               //if (upper || lower || both) {
+                                               if (true) { // Let's update the whole text, as some comment changes can alter everything
+                                                       min = Math.min(start, min);
+                                                       max = Math.max(max, start + length);
+                                                       if (t.getType() == Token.IDENTIFIER) {
+                                                               boolean keyword = false;
+                                                               for (int index = 0; index < keywords.length; index++) {
+                                                                       if (value.equals(keywords[index])) {
+                                                                               keyword = true;
+                                                                       }
+                                                               }
+                                                               if (keyword) {
+                                                                       styleRange.fontStyle = SWT.BOLD;
+                                                                       styleRange.foreground = KEYWORD;
+                                                               } else {
+                                                                       styleRange.foreground = DEFAULT;
+                                                               }
+                                                               styles.addElement(styleRange);
+                                                       } else if (t.getType() == Token.COMMENT) {
+                                                               styleRange.foreground = COMMENT;
+                                                               styles.addElement(styleRange);
+                                                       } else if (t.getType() == Token.LITERAL) {
+                                                               styleRange.foreground = STRING_LITERAL;
+                                                               styles.addElement(styleRange);
+                                                       } else if (t.getType() == Token.NUMERIC) {
+                                                               styleRange.foreground = NUMERIC;
+                                                               styles.addElement(styleRange);
+                                                       } else {
+                                                               styles.addElement(styleRange);
+                                                       }
+                                               }
+                                       }
+                                       StyleRange[] ranges = new StyleRange[styles.size()];
+                                       for (int k = 0; k < ranges.length; k++) {
+                                               ranges[k] = (StyleRange) styles.elementAt(k);
+                                       }
+                                       if (max >= 0 && ranges.length > 0) {
+                                               setStyles(ranges, min, max - min);
+                                       }
+                                       long endTime = System.currentTimeMillis();
+                                       parseTime = subTime - startTime;
+                                       fullTime = endTime - startTime;
+                               } catch (NoSuchElementException e) {
+                                       // ignore a missing request
+                               } catch (InterruptedException e) {
+                                       // ignore any interruptions
+                               }
+                       }
+               }
+       }
+       public void setStyles(final StyleRange[] styles, final int start, final int length) {
+               getViewSite().getShell().getDisplay().asyncExec(new Runnable() {
+                       public void run() {
+                               try {
+                                       for (int i = 0; i < styles.length; i++) {
+                                               widget.setStyleRange(styles[i]);
+                                       }
+                               } catch (Throwable t) {
+                                       System.out.println("Error with styles: " + t.getClass().toString()); //$NON-NLS-1$
+                                       // ignore any errors
+                               }
+                       }
+               });
+       }
+       
+       ExtendedModifyListener modifyListener = new ExtendedModifyListener() {
+               public void modifyText(ExtendedModifyEvent event) {
+                       textUpdater.updateText(getQuery(), event.start, event.length);
+               }
+       };
+               
+       private Action cutAction = new Action() {
+               public void run() {
+                       widget.cut();
+               }
+       };
+       private Action copyAction = new Action() {
+               public void run() {
+                       widget.copy();
+               }
+       };
+       private Action pasteAction = new Action() {
+               public void run() {
+                       widget.paste();
+               }
+       };
+       private Action selectAllAction = new Action() {
+               public void run() {
+                       widget.selectAll();
+               }
+       };
+}