Skip to content

Commit

Permalink
Refactoring; add QueryTask; add connect/disconnect popup from EditorS…
Browse files Browse the repository at this point in the history
…tatusBar
  • Loading branch information
dzmipt committed Jun 28, 2024
1 parent 224bada commit 5612566
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 77 deletions.
1 change: 1 addition & 0 deletions notes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* Server connect/disconnect actions from status bar
* Server Add form prepopulate details of currently selected server
* Export as Excel
* Fixing timezone bug
Expand Down
4 changes: 4 additions & 0 deletions src/studio/kdb/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ public void close() {
kConn.close();
}

public void connect() throws IOException, K4Exception {
kConn.connect();
}

public Server getServer() {
return server;
}
Expand Down
5 changes: 5 additions & 0 deletions src/studio/ui/EditorPane.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import studio.ui.search.SearchPanel;
import studio.ui.search.SearchPanelListener;
import studio.ui.statusbar.EditorStatusBar;
import studio.ui.statusbar.EditorStatusBarCallback;
import studio.ui.statusbar.MainStatusBar;

import javax.swing.*;
Expand Down Expand Up @@ -71,6 +72,10 @@ public void setSessionConnected(boolean connected) {
editorStatusBar.setSessionConnected(connected);
}

public void setEditorStatusBarCallback(EditorStatusBarCallback callback) {
editorStatusBar.setEditorStatusBarCallback(callback);
}

@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if ((e.getModifiers() & StudioWindow.menuShortcutKeyMask) == 0) return;
Expand Down
65 changes: 64 additions & 1 deletion src/studio/ui/EditorTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import studio.kdb.Server;
import studio.kdb.Session;
import studio.ui.action.QueryExecutor;
import studio.ui.action.QueryResult;
import studio.ui.action.QueryTask;
import studio.ui.rstextarea.StudioRSyntaxTextArea;
import studio.ui.statusbar.EditorStatusBarCallback;
import studio.utils.Content;
import studio.utils.FileReaderWriter;
import studio.utils.FileWatcher;
Expand All @@ -16,6 +19,8 @@
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
Expand All @@ -27,7 +32,7 @@
import java.util.Objects;
import java.util.stream.Stream;

public class EditorTab implements FileWatcher.Listener {
public class EditorTab implements FileWatcher.Listener, EditorStatusBarCallback {

private String title;
private String filename = null;
Expand All @@ -47,6 +52,9 @@ public class EditorTab implements FileWatcher.Listener {

private static final Logger log = LogManager.getLogger();

private final static Cursor textCursor = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
private final static Cursor waitCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);

public EditorTab(StudioWindow studioWindow) {
this.studioWindow = studioWindow;
init();
Expand All @@ -67,6 +75,7 @@ private void init() {
if (editorPane != null) throw new IllegalStateException("The EditorTab has been already initialized");

editorPane = new EditorPane(true, studioWindow.getEditorSearchPanel(), studioWindow.getMainStatusBar());
editorPane.setEditorStatusBarCallback(this);
editorPane.setFocusable(false);
RSyntaxTextArea textArea = editorPane.getTextArea();
textArea.setName("editor" + studioWindow.nextEditorNameIndex());
Expand Down Expand Up @@ -106,6 +115,60 @@ public void init(Content content) {
textArea.requestFocus();
}

public void executeQuery(QueryTask queryTask) {
if (server == Server.NO_SERVER) {
log.info("Server is not set. Can't execute the query");
return;
}
getTextArea().setCursor(waitCursor);
editorPane.setEditorStatus("Executing: " + queryTask.getQueryText());
getQueryExecutor().execute(queryTask);
editorPane.startClock();
studioWindow.refreshActionState();
}

// if the query is cancelled execTime=-1, result and error are null's
public void queryExecutionComplete(QueryResult queryResult) {
editorPane.stopClock();
JTextComponent textArea = getTextArea();
textArea.setCursor(textCursor);
if (queryResult.isComplete()) {
long execTime = queryResult.getExecutionTimeInMS();
editorPane.setEditorStatus("Last execution time: " + (execTime > 0 ? "" + execTime : "<1") + " ms");
} else {
editorPane.setEditorStatus("Last query was cancelled");
}

try {
if (queryResult.hasResultObject()) {
studioWindow.addResultTab(queryResult, "Executed at server: " + queryResult.getServer().getDescription(true) );
}
} catch (Throwable error) {
log.error("Error during result rendering", error);

String message = error.getMessage();
if ((message == null) || (message.length() == 0))
message = "No message with exception. Exception is " + error;
StudioOptionPane.showError(editorPane,
"\nAn unexpected error occurred whilst communicating with " +
server.getConnectionString() +
"\n\nError detail is\n\n" + message + "\n\n",
"Studio for kdb+");
}

studioWindow.refreshActionState();
}

@Override
public void connect() {
executeQuery(QueryTask.connect());
}

@Override
public void disconnect() {
session.close();
}

private void dropFiles(File... files) {
files = Stream.of(files)
.filter(File::isFile)
Expand Down
60 changes: 3 additions & 57 deletions src/studio/ui/StudioWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
import studio.core.Studio;
import studio.kdb.*;
import studio.kdb.config.ActionOnExit;
import studio.ui.action.ConnectionStats;
import studio.ui.action.QPadImport;
import studio.ui.action.QueryResult;
import studio.ui.action.WorkspaceSaver;
import studio.ui.action.*;
import studio.ui.chart.Chart;
import studio.ui.dndtabbedpane.DragEvent;
import studio.ui.dndtabbedpane.DraggableTabbedPane;
Expand Down Expand Up @@ -153,8 +150,6 @@ public class StudioWindow extends JFrame implements WindowListener {
private final List<Server> serverHistory;

public final static int menuShortcutKeyMask = java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private final static Cursor textCursor = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
private final static Cursor waitCursor = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);

private final static int MAX_SERVERS_TO_CLONE = 20;

Expand Down Expand Up @@ -1544,7 +1539,7 @@ public static void loadWorkspace(Workspace workspace) {
}

public void refreshQuery() {
executeK4Query(lastQuery);
editor.executeQuery(QueryTask.query(lastQuery));
}

public void executeQueryCurrentLine() {
Expand All @@ -1565,7 +1560,7 @@ private void executeQuery(String text) {
return;
}

executeK4Query(text);
editor.executeQuery(QueryTask.query(text));
lastQuery = text;
}

Expand Down Expand Up @@ -1651,22 +1646,6 @@ private JTable getSelectedTable() {
return grid.getTable();
}

private void executeK4Query(String text) {
executeK4Query(new K.KCharacterVector(text), text);
}

void executeK4Query(K.KBase query, String queryText) {
if (editor.getServer() == Server.NO_SERVER) {
log.info("Server is not set. Can't execute the query");
return;
}
editor.getTextArea().setCursor(waitCursor);
editor.getPane().setEditorStatus("Executing: " + queryText);
editor.getQueryExecutor().execute(query, queryText);
editor.getPane().startClock();
refreshActionState();
}

private TabPanel getResultPane(int index) {
return (TabPanel)tabbedPane.getComponentAt(index);
}
Expand Down Expand Up @@ -1703,39 +1682,6 @@ private static String getTooltipText(String tooltip, KMessage message) {
return res.toString();
}

// if the query is cancelled execTime=-1, result and error are null's
public static void queryExecutionComplete(EditorTab editor, QueryResult queryResult) {
editor.getPane().stopClock();
JTextComponent textArea = editor.getTextArea();
textArea.setCursor(textCursor);
if (queryResult.isComplete()) {
long execTime = queryResult.getExecutionTimeInMS();
editor.getPane().setEditorStatus("Last execution time: " + (execTime > 0 ? "" + execTime : "<1") + " ms");
} else {
editor.getPane().setEditorStatus("Last query was cancelled");
}

StudioWindow window = editor.getStudioWindow();
try {
if (queryResult.isComplete()) {
window.addResultTab(queryResult, "Executed at server: " + queryResult.getServer().getDescription(true) );
}
} catch (Throwable error) {
log.error("Error during result rendering", error);

String message = error.getMessage();
if ((message == null) || (message.length() == 0))
message = "No message with exception. Exception is " + error;
StudioOptionPane.showError(editor.getPane(),
"\nAn unexpected error occurred whilst communicating with " +
editor.getServer().getConnectionString() +
"\n\nError detail is\n\n" + message + "\n\n",
"Studio for kdb+");
}

window.refreshActionState();
}

public static Workspace getWorkspace() {
Workspace workspace = new Workspace();
Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
Expand Down
3 changes: 2 additions & 1 deletion src/studio/ui/TabPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import studio.kdb.ListModel;
import studio.kdb.*;
import studio.ui.action.QueryResult;
import studio.ui.action.QueryTask;

import javax.swing.*;
import javax.swing.border.EtchedBorder;
Expand Down Expand Up @@ -65,7 +66,7 @@ private void upload() {
String varName = StudioOptionPane.showInputDialog(studioWindow, "Enter variable name", "Upload to Server");
if (varName == null) return;
varName = varName.trim();
studioWindow.executeK4Query(new K.KList(new K.Function("{x set y}"), new K.KSymbol(varName), result), "<upload to server>");
studioWindow.getActiveEditor().executeQuery(QueryTask.upload(varName, result));
}

private void initComponents() {
Expand Down
4 changes: 4 additions & 0 deletions src/studio/ui/UserAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public static UserAction create(String text,
return create(text, null, desc, mnemonic, null, listener);
}

public static UserAction create(String text, Icon icon, ActionListener listener) {
return create(text, icon, null, 0, null, listener);
}

public static UserAction create(String text, ActionListener listener) {
return create(text, null, null, 0, null, listener);
}
Expand Down
32 changes: 16 additions & 16 deletions src/studio/ui/action/QueryExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
import kx.ProgressCallback;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import studio.kdb.K;
import studio.kdb.Server;
import studio.kdb.Session;
import studio.ui.EditorTab;
import studio.ui.StudioWindow;

import javax.swing.*;
import java.util.concurrent.atomic.AtomicInteger;
Expand All @@ -35,8 +33,8 @@ public QueryExecutor(EditorTab editor) {
this.editor = editor;
}

public void execute(K.KBase query, String queryText) {
worker = new Worker(queryIndex.getAndIncrement(), editor, query, queryText);
public void execute(QueryTask queryTask) {
worker = new Worker(queryIndex.getAndIncrement(), editor, queryTask);
worker.execute();
}

Expand Down Expand Up @@ -99,17 +97,15 @@ private class Worker extends SwingWorker<QueryResult, Integer> {

private volatile EditorTab editor;
private volatile Server server;
private volatile K.KBase query;
private volatile String queryText;
private QueryTask queryTask;
private final int queryIndex;
private volatile Session session = null;

public Worker(int queryIndex, EditorTab editor, K.KBase query, String queryText) {
public Worker(int queryIndex, EditorTab editor, QueryTask queryTask) {
this.queryIndex = queryIndex;
this.editor = editor;
this.server = editor.getServer();
this.query = query;
this.queryText = queryText;
this.queryTask = queryTask;
}

void closeConnection() {
Expand All @@ -126,11 +122,11 @@ private Session getSession() {

@Override
protected QueryResult doInBackground() {
QueryResult result = new QueryResult(server, queryText);
queryLog.info("#{}: query {}({})\n{}",queryIndex, server.getFullName(), server.getConnectionString(), queryText);
QueryResult result = new QueryResult(server, queryTask.getQueryText());
queryLog.info("#{}: query {}({})\n{}",queryIndex, server.getFullName(), server.getConnectionString(), queryTask.getQueryText());
try {
session = getSession();
KMessage response = session.execute(query, QueryExecutor.this);
KMessage response = queryTask.execute(session, QueryExecutor.this);
result.setResult(response);
} catch (Throwable e) {
if (! (e instanceof K4Exception)) {
Expand All @@ -146,7 +142,11 @@ protected QueryResult doInBackground() {
queryLog.info("#{}: error during execution {} {}", queryIndex, result.getError().getClass().getName(), result.getError().getMessage());
}
} else {
queryLog.info("#{}: type={}, count={}, time={}", queryIndex, result.getResult().getType(), result.getResult().count(), result.getExecutionTimeInMS());
if (queryTask.returnResult()) {
queryLog.info("#{}: type={}, count={}, time={}", queryIndex, result.getResult().getType(), result.getResult().count(), result.getExecutionTimeInMS());
} else {
queryLog.info("#{}: task={}, time={}", queryIndex, queryTask.getQueryText(), result.getExecutionTimeInMS());
}
}
return result;
}
Expand All @@ -159,14 +159,14 @@ protected void done() {
try {
QueryResult result;
if (isCancelled()) {
result = new QueryResult(server, queryText);
result = new QueryResult(server, queryTask.getQueryText());
queryLog.info("#{}: Cancelled", queryIndex);
} else {
result = get();
}
StudioWindow.queryExecutionComplete(editor, result);
editor.queryExecutionComplete(result);
} catch (Exception e) {
log.error("Ops... It wasn't expected", e);
log.error("Oops... It wasn't expected", e);
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions src/studio/ui/action/QueryResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ public QueryResult(Server server, String query) {

public void setResult(KMessage result) {
this.result = result;
Throwable error = result.getError();
if (error != null) setError(error);
if (result != null) {
Throwable error = result.getError();
if (error != null) setError(error);
}
complete = true;
}

Expand All @@ -35,6 +37,10 @@ public void setError(Throwable error) {
complete = true;
}

public boolean hasResultObject() {
return result != null || error != null;
}

public boolean isComplete() {
return complete;
}
Expand Down
Loading

0 comments on commit 5612566

Please sign in to comment.