SQL Plugin copied from Quantum plugin and refactored for PHPEclipse
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.sql / src / net / sourceforge / phpdt / sql / view / SQLQueryView.java
diff --git a/archive/net.sourceforge.phpeclipse.sql/src/net/sourceforge/phpdt/sql/view/SQLQueryView.java b/archive/net.sourceforge.phpeclipse.sql/src/net/sourceforge/phpdt/sql/view/SQLQueryView.java
new file mode 100644 (file)
index 0000000..4756d02
--- /dev/null
@@ -0,0 +1,405 @@
+package net.sourceforge.phpdt.sql.view;
+
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import net.sourceforge.phpdt.sql.PHPEclipseSQLPlugin;
+
+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.dnd.Clipboard;
+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.IWorkbenchActionConstants;
+import org.eclipse.ui.part.ViewPart;
+
+import net.sourceforge.phpdt.sql.actions.ExecuteAction;
+import net.sourceforge.phpdt.sql.actions.ExportQueryAction;
+import net.sourceforge.phpdt.sql.actions.ImportQueryAction;
+import net.sourceforge.phpdt.sql.sql.MultiSQLServer;
+import net.sourceforge.phpdt.sql.parser.SQLLexx;
+import net.sourceforge.phpdt.sql.parser.Token;
+
+public class SQLQueryView extends ViewPart {
+       private ExecuteAction executeAction;
+       private ImportQueryAction importQueryAction;
+       private ExportQueryAction exportQueryAction;
+       private Clipboard clip;
+       private Label statusImage;
+       private Label status;
+       private ProgressBar progress;
+       private static SQLQueryView instance = null;
+       private StyledText widget;
+       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() {
+               widget.setFocus();
+       }
+       public static SQLQueryView getInstance() {
+               return instance;
+       }
+
+       public void createPartControl(org.eclipse.swt.widgets.Composite parent) {
+               instance = this;
+               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);
+               clip = new Clipboard(getSite().getShell().getDisplay());
+               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(PHPEclipseSQLPlugin.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(PHPEclipseSQLPlugin.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(PHPEclipseSQLPlugin.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(PHPEclipseSQLPlugin.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("");
+                       }
+               });
+
+               item = new ToolItem(toolbar, SWT.SEPARATOR);
+
+               item = new ToolItem(toolbar, SWT.PUSH);
+               final ToolItem commit = item;
+               item.setImage(PHPEclipseSQLPlugin.getImage("commit.gif")); //$NON-NLS-1$
+               item.setToolTipText("Commit");
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               MultiSQLServer.getInstance().commit();
+                       }
+               });
+               item.setEnabled(false);
+               
+               item = new ToolItem(toolbar, SWT.PUSH);
+               final ToolItem rollback = item;
+               item.setImage(PHPEclipseSQLPlugin.getImage("rollback.gif")); //$NON-NLS-1$
+               item.setToolTipText("RollBack");
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               MultiSQLServer.getInstance().rollback();
+                       }
+               });
+               item.setEnabled(false);
+               
+               item = new ToolItem(toolbar, SWT.CHECK);
+               final ToolItem autocommit = item;
+               item.setImage(PHPEclipseSQLPlugin.getImage("autocommit.gif")); //$NON-NLS-1$
+               item.setToolTipText("AutoCommit");
+               item.addSelectionListener(new SelectionListener() {
+                       public void widgetDefaultSelected(SelectionEvent e) {
+                       }
+                       public void widgetSelected(SelectionEvent e) {
+                               MultiSQLServer.getInstance().setAutoCommit(autocommit.getSelection());
+                               if (autocommit.getSelection()) {
+                                       commit.setEnabled(false);
+                                       rollback.setEnabled(false);
+                               } else {
+                                       commit.setEnabled(true);
+                                       rollback.setEnabled(true);
+                               }
+                       }
+               });
+               item.setSelection(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"));
+               statusImage.setImage(PHPEclipseSQLPlugin.getImage("success.gif"));
+               progress.setMinimum(0);
+       }
+
+       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 = {"SELECT", "DROP", "FROM", 
+               "INSERT", "INTO", "VALUES",
+               "CREATE", "TABLE", "VIEW", "SEQUENCE",
+               "UPDATE", "SET", "WHERE"};
+
+       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) {
+                                                       min = Math.min(start, min);
+                                                       max = Math.max(max, start + length);
+                                                       if (t.getType() == t.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() == t.COMMENT) {
+                                                               styleRange.foreground = COMMENT;
+                                                               styles.addElement(styleRange);
+                                                       } else if (t.getType() == t.LITERAL) {
+                                                               styleRange.foreground = STRING_LITERAL;
+                                                               styles.addElement(styleRange);
+                                                       } else if (t.getType() == t.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());
+                                       // 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();
+               }
+       };
+}