Added a listener for assessing executions.

This commit is contained in:
Andrew Lalis 2020-03-11 01:14:50 +01:00
parent 724359d651
commit 8dd443295c
8 changed files with 149 additions and 35 deletions

View File

@ -3,7 +3,10 @@ package com.gyrobian.database;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* Represents a result set from a SELECT query. * Represents a result set from a SELECT query.
@ -30,6 +33,12 @@ public class CachedResultSet {
return this.rows; return this.rows;
} }
/**
* Constructs a new cached result set from an actual result set.
* @param resultSet The result set to gather data from.
* @return A cached result set that can be used later.
* @throws SQLException If an error occurs while reading the result set.
*/
public static CachedResultSet fromResultSet(ResultSet resultSet) throws SQLException { public static CachedResultSet fromResultSet(ResultSet resultSet) throws SQLException {
ResultSetMetaData metaData = resultSet.getMetaData(); ResultSetMetaData metaData = resultSet.getMetaData();
@ -51,6 +60,9 @@ public class CachedResultSet {
return new CachedResultSet(columnNames, rows); return new CachedResultSet(columnNames, rows);
} }
/**
* @return This result set, formatted as an ASCII table.
*/
public String toFormattedTableString() { public String toFormattedTableString() {
int[] optimumColumnWidths = new int[this.columnNames.length]; int[] optimumColumnWidths = new int[this.columnNames.length];
int totalTableWidth = 0; int totalTableWidth = 0;
@ -84,12 +96,4 @@ public class CachedResultSet {
} }
return sb.toString(); return sb.toString();
} }
@Override
public String toString() {
return "CachedResultSet{" +
"columnNames=" + Arrays.toString(columnNames) +
", rows=" + rows +
'}';
}
} }

View File

@ -14,6 +14,10 @@ public class ExecutionLog {
this.actions = new ArrayList<>(); this.actions = new ArrayList<>();
} }
/**
* Records a new action.
* @param action The action to record.
*/
public void recordAction(ExecutionAction action) { public void recordAction(ExecutionAction action) {
this.actions.add(action); this.actions.add(action);
} }
@ -21,4 +25,16 @@ public class ExecutionLog {
public List<ExecutionAction> getActions() { public List<ExecutionAction> getActions() {
return this.actions; return this.actions;
} }
/**
* @return True if there's an exception somewhere in this execution log, or false otherwise.
*/
public boolean containsExceptions() {
for (ExecutionAction action : this.getActions()) {
if (action.getException() != null) {
return true;
}
}
return false;
}
} }

View File

@ -0,0 +1,71 @@
package com.gyrobian.listener;
import com.gyrobian.database.ExecutionLog;
import com.gyrobian.view.AssessmentDisplay;
import com.gyrobian.view.ExecutionLogDisplay;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Listener for when pressing a button triggers comparing the executions of the template and testing
* scripts.
*/
public class AssessExecutionsListener implements ActionListener {
private ExecutionLogDisplay templateExecutionLogDisplay;
private ExecutionLogDisplay testingExecutionLogDisplay;
private JButton executeTemplateButton;
private JButton executeTestingButton;
private AssessmentDisplay assessmentDisplay;
public AssessExecutionsListener(
ExecutionLogDisplay templateExecutionLogDisplay,
ExecutionLogDisplay testingExecutionLogDisplay,
JButton executeTemplateButton,
JButton executeTestingButton,
AssessmentDisplay assessmentDisplay
) {
this.templateExecutionLogDisplay = templateExecutionLogDisplay;
this.testingExecutionLogDisplay = testingExecutionLogDisplay;
this.executeTemplateButton = executeTemplateButton;
this.executeTestingButton = executeTestingButton;
this.assessmentDisplay = assessmentDisplay;
}
/**
* Invoked when an action occurs.
*
* @param e the event to be processed
*/
@Override
public void actionPerformed(ActionEvent e) {
ExecutionLog lastTemplateExecution = this.templateExecutionLogDisplay.getLastExecutionLogDisplayed();
ExecutionLog lastTestingExecution = this.testingExecutionLogDisplay.getLastExecutionLogDisplayed();
if (lastTemplateExecution == null || lastTestingExecution == null) {
this.assessmentDisplay.appendToDocument("Could not find a recent execution for one of the scripts, re-running...\n", null);
triggerButton(this.executeTemplateButton, this);
triggerButton(this.executeTestingButton, this);
lastTemplateExecution = this.templateExecutionLogDisplay.getLastExecutionLogDisplayed();
lastTestingExecution = this.testingExecutionLogDisplay.getLastExecutionLogDisplayed();
if (lastTemplateExecution == null || lastTestingExecution == null) {
JOptionPane.showMessageDialog(this.assessmentDisplay, "Could not execute both scripts.", "Assessment Error", JOptionPane.WARNING_MESSAGE);
return;
}
}
}
/**
* Triggers all action listeners on a particular button.
* @param button The button to trigger.
* @param source The object that triggered the button.
*/
private static void triggerButton(JButton button, Object source) {
for (ActionListener listener : button.getActionListeners()) {
listener.actionPerformed(new ActionEvent(source, ActionEvent.ACTION_PERFORMED, null));
}
}
}

View File

@ -0,0 +1,25 @@
package com.gyrobian.view;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyledDocument;
/**
* A slightly modified text pane that makes appending text a bit easier.
*/
public class AppendableJTextPane extends JTextPane {
/**
* Appends a styled string to the document.
* @param str The string to append.
* @param style The style to use for the string.
*/
public void appendToDocument(String str, Style style) {
StyledDocument document = this.getStyledDocument();
try {
document.insertString(document.getLength(), str, style);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,7 @@
package com.gyrobian.view;
/**
* A text pane that's specially suited for displaying the results of assessing two execution logs.
*/
public class AssessmentDisplay extends AppendableJTextPane {
}

View File

@ -2,17 +2,14 @@ package com.gyrobian.view;
import com.gyrobian.database.*; import com.gyrobian.database.*;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style; import javax.swing.text.Style;
import javax.swing.text.StyleConstants; import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*; import java.awt.*;
/** /**
* A type of text pane that's built for displaying SQL script execution logs. * A type of text pane that's built for displaying SQL script execution logs.
*/ */
public class ExecutionLogDisplay extends JTextPane { public class ExecutionLogDisplay extends AppendableJTextPane {
private Style timestampStyle; private Style timestampStyle;
private Style actionSubsectionLabelStyle; private Style actionSubsectionLabelStyle;
@ -93,20 +90,6 @@ public class ExecutionLogDisplay extends JTextPane {
StyleConstants.setBold(this.exceptionStyle, true); StyleConstants.setBold(this.exceptionStyle, true);
} }
/**
* Appends a styled string to the document.
* @param str The string to append.
* @param style The style to use for the string.
*/
private void appendToDocument(String str, Style style) {
StyledDocument document = this.getStyledDocument();
try {
document.insertString(document.getLength(), str, style);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
/** /**
* Overrides the behavior of JTextPane so that any time this display's text disappears, we wipe * Overrides the behavior of JTextPane so that any time this display's text disappears, we wipe
* any memory of a previous execution log. * any memory of a previous execution log.

View File

@ -161,7 +161,7 @@
<properties/> <properties/>
<border type="bevel-lowered"/> <border type="bevel-lowered"/>
<children> <children>
<component id="8cfc7" class="javax.swing.JLabel" binding="assessmentPanelTitle"> <component id="8cfc7" class="javax.swing.JLabel">
<constraints> <constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints> </constraints>
@ -178,9 +178,8 @@
</properties> </properties>
<border type="none"/> <border type="none"/>
<children> <children>
<component id="c7cae" class="javax.swing.JTextPane" binding="assessmentTextPane"> <component id="cc18d" class="com.gyrobian.view.AssessmentDisplay" binding="assessmentTextPane" custom-create="true">
<constraints/> <constraints/>
<properties/>
</component> </component>
</children> </children>
</scrollpane> </scrollpane>
@ -441,10 +440,10 @@
<properties/> <properties/>
<border type="none"/> <border type="none"/>
<children> <children>
<component id="3cdeb" class="javax.swing.JButton" binding="compareExecutionsButton"> <component id="3cdeb" class="javax.swing.JButton" binding="assessExecutionsButton">
<constraints/> <constraints/>
<properties> <properties>
<text value="Compare Template and Testing Scripts"/> <text value="Assess Template and Testing Scripts"/>
</properties> </properties>
</component> </component>
</children> </children>

View File

@ -1,5 +1,6 @@
package com.gyrobian.view; package com.gyrobian.view;
import com.gyrobian.listener.AssessExecutionsListener;
import com.gyrobian.listener.ClearTextComponentListener; import com.gyrobian.listener.ClearTextComponentListener;
import com.gyrobian.listener.LoadTextComponentFromFileListener; import com.gyrobian.listener.LoadTextComponentFromFileListener;
import com.gyrobian.listener.ScriptExecutionListener; import com.gyrobian.listener.ScriptExecutionListener;
@ -33,8 +34,7 @@ public class Window extends JFrame {
private JPanel testingOutputPanel; private JPanel testingOutputPanel;
private ExecutionLogDisplay templateOutputTextPane; private ExecutionLogDisplay templateOutputTextPane;
private ExecutionLogDisplay testingOutputTextPane; private ExecutionLogDisplay testingOutputTextPane;
private JLabel assessmentPanelTitle; private AssessmentDisplay assessmentTextPane;
private JTextPane assessmentTextPane;
private JPanel mainControlPanel; private JPanel mainControlPanel;
private JButton executeBothButton; private JButton executeBothButton;
private JButton executeTemplateButton; private JButton executeTemplateButton;
@ -44,7 +44,7 @@ public class Window extends JFrame {
private JTextField jdbcUrlInput; private JTextField jdbcUrlInput;
private JCheckBox enableForeignKeysCheckbox; private JCheckBox enableForeignKeysCheckbox;
private JButton clearExecutionOutputsButton; private JButton clearExecutionOutputsButton;
private JButton compareExecutionsButton; private JButton assessExecutionsButton;
public Window() { public Window() {
super("SQL-Assesser-2"); super("SQL-Assesser-2");
@ -83,10 +83,19 @@ public class Window extends JFrame {
this.executeTestingButton.addActionListener(executeTestingListener); this.executeTestingButton.addActionListener(executeTestingListener);
this.executeBothButton.addActionListener(executeTemplateListener); this.executeBothButton.addActionListener(executeTemplateListener);
this.executeBothButton.addActionListener(executeTestingListener); this.executeBothButton.addActionListener(executeTestingListener);
this.assessExecutionsButton.addActionListener(new AssessExecutionsListener(
this.templateOutputTextPane,
this.testingOutputTextPane,
this.executeTemplateButton,
this.executeTestingButton,
this.assessmentTextPane
));
} }
protected void createUIComponents() { protected void createUIComponents() {
this.templateOutputTextPane = new ExecutionLogDisplay(); this.templateOutputTextPane = new ExecutionLogDisplay();
this.testingOutputTextPane = new ExecutionLogDisplay(); this.testingOutputTextPane = new ExecutionLogDisplay();
this.assessmentTextPane = new AssessmentDisplay();
} }
} }