[#1472] Add a Settings.executeDebugging property, and move

server-side Console logic to core

 - API refactoring: Moved QueryMatcher property from Debugger to
LoggingListener, to simplify API evolution (possibility of
multiple LoggingListeners)
 - Use jOOQ terminology: Query instead of Statement
This commit is contained in:
Lukas Eder 2012-09-11 20:22:05 +02:00
parent 1cc79a4dfb
commit 9d190ff7ca
13 changed files with 395 additions and 370 deletions

View File

@ -89,11 +89,11 @@ public class BreakpointEditor extends JPanel {
private JComboBox breakpointTypeComboBox;
private JPanel processorPane;
private JCheckBox beforeExecutionCheckBox;
private StatementProcessorPane beforeExecutionProcessorPane;
private QueryProcessorPane beforeExecutionProcessorPane;
private JComboBox executeTypeComboBox;
private StatementProcessorPane replacementExecutionProcessorPane;
private QueryProcessorPane replacementExecutionProcessorPane;
private JCheckBox afterExecutionCheckBox;
private StatementProcessorPane afterExecutionProcessorPane;
private QueryProcessorPane afterExecutionProcessorPane;
public BreakpointEditor(final DebuggerPane debuggerPane, Breakpoint breakpoint) {
super(new GridBagLayout());
@ -104,7 +104,7 @@ public class BreakpointEditor extends JPanel {
queryMatcher = new QueryMatcher(null, null, null, true);
}
int y = 0;
TextMatcher statementTextMatcher = queryMatcher.getStatementTextMatcher();
TextMatcher statementTextMatcher = queryMatcher.getQueryTextMatcher();
statementTextMatcherCheckBox = new JCheckBox("Statement", statementTextMatcher != null);
statementTextMatcherCheckBox.setOpaque(false);
statementTextMatcherCheckBox.addItemListener(new ItemListener() {
@ -221,7 +221,7 @@ public class BreakpointEditor extends JPanel {
}
});
processorPane.add(beforeExecutionCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 0, 0, 0), 0, 0));
beforeExecutionProcessorPane = new StatementProcessorPane(beforeExecutionProcessor);
beforeExecutionProcessorPane = new QueryProcessorPane(beforeExecutionProcessor);
processorPane.add(beforeExecutionProcessorPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 5, 0, 0), 0, 0));
y++;
QueryProcessor replacementExecutionProcessor = breakpoint.getReplacementExecutionProcessor();
@ -236,7 +236,7 @@ public class BreakpointEditor extends JPanel {
executeTypeComboBox.setSelectedIndex(0);
}
processorPane.add(executeTypeComboBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
replacementExecutionProcessorPane = new StatementProcessorPane(breakpoint.getReplacementExecutionProcessor());
replacementExecutionProcessorPane = new QueryProcessorPane(breakpoint.getReplacementExecutionProcessor());
processorPane.add(replacementExecutionProcessorPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 0), 0, 0));
executeTypeComboBox.addItemListener(new ItemListener() {
@Override
@ -256,7 +256,7 @@ public class BreakpointEditor extends JPanel {
}
});
processorPane.add(afterExecutionCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(2, 0, 0, 0), 0, 0));
afterExecutionProcessorPane = new StatementProcessorPane(afterExecutionProcessor);
afterExecutionProcessorPane = new QueryProcessorPane(afterExecutionProcessor);
processorPane.add(afterExecutionProcessorPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(2, 5, 0, 0), 0, 0));
}
@ -325,9 +325,9 @@ public class BreakpointEditor extends JPanel {
QueryProcessor replacementExecutionProcessor = null;
QueryProcessor afterExecutionProcessor = null;
if(!isBreaking) {
beforeExecutionProcessor = beforeExecutionCheckBox.isSelected()? beforeExecutionProcessorPane.getStatementProcessor(): null;
replacementExecutionProcessor = executeTypeComboBox.getSelectedIndex() == 1? replacementExecutionProcessorPane.getStatementProcessor(): null;
afterExecutionProcessor = afterExecutionCheckBox.isSelected()? afterExecutionProcessorPane.getStatementProcessor(): null;
beforeExecutionProcessor = beforeExecutionCheckBox.isSelected()? beforeExecutionProcessorPane.getQueryProcessor(): null;
replacementExecutionProcessor = executeTypeComboBox.getSelectedIndex() == 1? replacementExecutionProcessorPane.getQueryProcessor(): null;
afterExecutionProcessor = afterExecutionCheckBox.isSelected()? afterExecutionProcessorPane.getQueryProcessor(): null;
}
return new Breakpoint(id, hitCount, queryMatcher, isBreaking, beforeExecutionProcessor, replacementExecutionProcessor, afterExecutionProcessor);
}

View File

@ -118,40 +118,51 @@ import org.fife.ui.rtextarea.RTextScrollPane;
@SuppressWarnings({"serial", "hiding"})
public class LoggerPane extends JPanel {
private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");
private static final String LS = System.getProperty("line.separator");
private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS");
private static final int MAX_NUMBER_OF_ROWS = 10000;
private static final int COLUMN_LINE = 0;
private static final int COLUMN_TYPE = 1;
private static final int COLUMN_THREAD = 2;
private static final int COLUMN_TIMESTAMP = 3;
private static final int COLUMN_PS_PREPARATION_DURATION = 4;
private static final int COLUMN_PS_BINDING_DURATION = 5;
private static final int COLUMN_EXEC_TIME = 6;
private static final int COLUMN_RS_LIFETIME = 7;
private static final int COLUMN_RS_READ = 8;
private static final int COLUMN_RS_READ_ROWS = 9;
private static final int COLUMN_DUPLICATION_COUNT = 10;
private static final int COLUMN_QUERY = 11;
private static final int COLUMN_COUNT = COLUMN_QUERY + 1;
private static final int COLUMN_LINE = 0;
private static final int COLUMN_TYPE = 1;
private static final int COLUMN_THREAD = 2;
private static final int COLUMN_TIMESTAMP = 3;
private static final int COLUMN_PS_PREPARATION_DURATION = 4;
private static final int COLUMN_PS_BINDING_DURATION = 5;
private static final int COLUMN_EXEC_TIME = 6;
private static final int COLUMN_RS_LIFETIME = 7;
private static final int COLUMN_RS_READ = 8;
private static final int COLUMN_RS_READ_ROWS = 9;
private static final int COLUMN_DUPLICATION_COUNT = 10;
private static final int COLUMN_QUERY = 11;
private static final int COLUMN_COUNT = COLUMN_QUERY + 1;
private final ImageIcon INSERT_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlInsert16.png"));
private final ImageIcon UPDATE_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlUpdate16.png"));
private final ImageIcon DELETE_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlDelete16.png"));
private final ImageIcon OTHER_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlOther16.png"));
private final ImageIcon SELECT_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlSelect16.png"));
private final ImageIcon INSERT_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlInsert16.png"));
private final ImageIcon UPDATE_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlUpdate16.png"));
private final ImageIcon DELETE_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlDelete16.png"));
private final ImageIcon OTHER_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlOther16.png"));
private final ImageIcon SELECT_ICON = new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/SqlSelect16.png"));
private Debugger debugger;
private JTableX table;
private SqlTextArea textArea;
private JLabel loggerStatusLabel;
private JButton loggerOnButton;
private JButton loggerOffButton;
private JToggleButton statementMatcherButton;
private boolean isLogging;
private boolean isReadQueryTypeDisplayed = true;
private boolean isWriteQueryTypeDisplayed = true;
private boolean isOtherQueryTypeDisplayed = true;
private boolean isScrollLocked;
// UI components
private JTableX table;
private SqlTextArea textArea;
private JLabel loggerStatusLabel;
private JButton loggerOnButton;
private JButton loggerOffButton;
private JToggleButton queryMatcherButton;
private boolean isLogging;
private boolean isReadQueryTypeDisplayed = true;
private boolean isWriteQueryTypeDisplayed = true;
private boolean isOtherQueryTypeDisplayed = true;
private boolean isScrollLocked;
// Data and debug API
private final Debugger debugger;
private final LoggerPaneLoggingListener loggingListener;
private List<QueryDebuggingInfo> queryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
private List<QueryDebuggingInfo> displayedQueryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
private Map<List<String>, Integer> queriesToCountMap = new HashMap<List<String>, Integer>();
public LoggerPane(Debugger debugger) {
super(new BorderLayout());
@ -163,6 +174,7 @@ public class LoggerPane extends JPanel {
JToolBar loggerHeaderWestPanel = new JToolBar();
loggerHeaderWestPanel.setFloatable(false);
loggerHeaderWestPanel.setOpaque(false);
loggingListener = new LoggerPaneLoggingListener();
loggerOnButton = new JButton(new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/Paused16.png")));
loggerOnButton.setOpaque(false);
loggerOnButton.setFocusable(false);
@ -187,20 +199,20 @@ public class LoggerPane extends JPanel {
}
});
loggerHeaderWestPanel.add(loggerOffButton);
statementMatcherButton = new JToggleButton(new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/Filter16.png")));
statementMatcherButton.setOpaque(false);
statementMatcherButton.setFocusable(false);
statementMatcherButton.setToolTipText("Filter incoming statements");
adjustStatementMatcherButton();
statementMatcherButton.addActionListener(new ActionListener() {
queryMatcherButton = new JToggleButton(new ImageIcon(getClass().getResource("/org/jooq/debug/console/resources/Filter16.png")));
queryMatcherButton.setOpaque(false);
queryMatcherButton.setFocusable(false);
queryMatcherButton.setToolTipText("Filter incoming queries");
adjustQueryMatcherButton();
queryMatcherButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
statementMatcherButton.setSelected(true);
new StatementMatchersDialogBox(LoggerPane.this, LoggerPane.this.debugger).setVisible(true);
adjustStatementMatcherButton();
queryMatcherButton.setSelected(true);
new QueryMatchersDialogBox(LoggerPane.this, LoggerPane.this.debugger, loggingListener).setVisible(true);
adjustQueryMatcherButton();
}
});
loggerHeaderWestPanel.add(statementMatcherButton);
loggerHeaderWestPanel.add(queryMatcherButton);
loggerHeaderPanel.add(loggerHeaderWestPanel, BorderLayout.WEST);
JPanel loggerHeaderCenterPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2));
loggerHeaderCenterPanel.setOpaque(false);
@ -286,7 +298,7 @@ public class LoggerPane extends JPanel {
JToggleButton loggerReadQueryTypeToggleButton = new JToggleButton(SELECT_ICON, isReadQueryTypeDisplayed);
loggerReadQueryTypeToggleButton.setOpaque(false);
loggerReadQueryTypeToggleButton.setFocusable(false);
loggerReadQueryTypeToggleButton.setToolTipText("Show/hide read statements");
loggerReadQueryTypeToggleButton.setToolTipText("Show/hide read queries");
loggerReadQueryTypeToggleButton.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
@ -298,7 +310,7 @@ public class LoggerPane extends JPanel {
JToggleButton loggerWriteQueryTypeToggleButton = new JToggleButton(UPDATE_ICON, isWriteQueryTypeDisplayed);
loggerWriteQueryTypeToggleButton.setOpaque(false);
loggerWriteQueryTypeToggleButton.setFocusable(false);
loggerWriteQueryTypeToggleButton.setToolTipText("Show/hide modification statements");
loggerWriteQueryTypeToggleButton.setToolTipText("Show/hide modification queries");
loggerWriteQueryTypeToggleButton.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
@ -310,7 +322,7 @@ public class LoggerPane extends JPanel {
JToggleButton loggerOtherQueryTypeToggleButton = new JToggleButton(OTHER_ICON, isOtherQueryTypeDisplayed);
loggerOtherQueryTypeToggleButton.setOpaque(false);
loggerOtherQueryTypeToggleButton.setFocusable(false);
loggerOtherQueryTypeToggleButton.setToolTipText("Show/hide other types of statements");
loggerOtherQueryTypeToggleButton.setToolTipText("Show/hide other types of queries");
loggerOtherQueryTypeToggleButton.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
@ -369,11 +381,11 @@ public class LoggerPane extends JPanel {
return TIMESTAMP_FORMAT.format(new Date(queryDebuggingInfo.getTimestamp()));
}
case COLUMN_PS_PREPARATION_DURATION: {
Long duration = queryDebuggingInfo.getPrepardeStatementPreparationDuration();
Long duration = queryDebuggingInfo.getPreparedStatementPreparationDuration();
return duration == null? null: duration;
}
case COLUMN_PS_BINDING_DURATION: {
Long duration = queryDebuggingInfo.getPrepardeStatementBindingDuration();
Long duration = queryDebuggingInfo.getPreparedStatementBindingDuration();
return duration == null? null: duration;
}
case COLUMN_EXEC_TIME: {
@ -560,7 +572,7 @@ public class LoggerPane extends JPanel {
popupMenu.add(copyCellsToClipboardMenuItem);
}
if(selectedQueryDebuggingInfos.length > 0) {
JMenuItem copyToClipboardMenuItem = new JMenuItem("Copy " + (selectedQueryDebuggingInfos.length > 1? selectedQueryDebuggingInfos.length + " ": "") + "Statement Data to Clipboard");
JMenuItem copyToClipboardMenuItem = new JMenuItem("Copy " + (selectedQueryDebuggingInfos.length > 1? selectedQueryDebuggingInfos.length + " ": "") + "Query Data to Clipboard");
copyToClipboardMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -570,7 +582,7 @@ public class LoggerPane extends JPanel {
popupMenu.add(copyToClipboardMenuItem);
}
if(displayedQueryDebuggingInfoList.size() > 0) {
JMenuItem copyAllToClipboardMenuItem = new JMenuItem("Copy All Statements Data (" + displayedQueryDebuggingInfoList.size() + ") to Clipboard");
JMenuItem copyAllToClipboardMenuItem = new JMenuItem("Copy All Query Data (" + displayedQueryDebuggingInfoList.size() + ") to Clipboard");
copyAllToClipboardMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@ -658,15 +670,11 @@ public class LoggerPane extends JPanel {
loggerThreadCheckBox.setSelected(false);
}
private void adjustStatementMatcherButton() {
QueryMatcher[] loggingStatementMatchers = LoggerPane.this.debugger.getLoggingStatementMatchers();
statementMatcherButton.setSelected(loggingStatementMatchers != null);
private void adjustQueryMatcherButton() {
QueryMatcher[] matchers = loggingListener.getMatchers();
queryMatcherButton.setSelected(matchers != null);
}
private List<QueryDebuggingInfo> queryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
private List<QueryDebuggingInfo> displayedQueryDebuggingInfoList = new ArrayList<QueryDebuggingInfo>();
private Map<List<String>, Integer> queriesToCountMap = new HashMap<List<String>, Integer>();
private void refreshRows() {
int originalRowCount = displayedQueryDebuggingInfoList.size();
displayedQueryDebuggingInfoList.clear();
@ -685,8 +693,6 @@ public class LoggerPane extends JPanel {
updateStatusLabel();
}
private static final int MAX_NUMBER_OF_ROWS = 10000;
private void addRow(QueryDebuggingInfo queryDebuggingInfo) {
if(queryDebuggingInfoList.size() == MAX_NUMBER_OF_ROWS) {
QueryDebuggingInfo discaredDebuggingInfo = queryDebuggingInfoList.remove(0);
@ -765,7 +771,7 @@ public class LoggerPane extends JPanel {
public QueryDebuggingInfo(long timestamp, QueryLog queryLog) {
this.timestamp = timestamp;
this.queryLog = queryLog;
this.throwable = new Exception("Statement Stack trace");
this.throwable = new Exception("Query Stack trace");
throwable.setStackTrace(queryLog.getCallerStackTraceElements());
}
public long getTimestamp() {
@ -774,10 +780,10 @@ public class LoggerPane extends JPanel {
public QueryLog getQueryLoggingData() {
return queryLog;
}
public Long getPrepardeStatementPreparationDuration() {
public Long getPreparedStatementPreparationDuration() {
return queryLog.getPreparedStatementPreparationDuration();
}
public Long getPrepardeStatementBindingDuration() {
public Long getPreparedStatementBindingDuration() {
return queryLog.getPreparedStatementBindingDuration();
}
public long getExecutionDuration() {
@ -825,64 +831,79 @@ public class LoggerPane extends JPanel {
}
}
private static String LS = System.getProperty("line.separator");
public void setLogging(boolean isLogging) {
if(this.isLogging == isLogging) {
if (this.isLogging == isLogging) {
return;
}
this.isLogging = isLogging;
loggerOnButton.setVisible(!isLogging);
loggerOffButton.setVisible(isLogging);
if(isLogging) {
LoggingListener loggingListener = new LoggingListener() {
@Override
public void logQuery(QueryLog queryLog) {
debugQueries(new QueryDebuggingInfo(System.currentTimeMillis(), queryLog));
}
public void debugQueries(final QueryDebuggingInfo queryDebuggingInfo) {
if(!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
debugQueries(queryDebuggingInfo);
}
});
return;
}
addRow(queryDebuggingInfo);
}
@Override
public void logResult(final ResultLog resultLog) {
if(!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
logResult(resultLog);
}
});
return;
}
for(int i=queryDebuggingInfoList.size()-1; i>=0; i--) {
QueryDebuggingInfo queryDebuggingInfo = queryDebuggingInfoList.get(i);
if(queryDebuggingInfo.getQueryLoggingData().getID() == resultLog.getQueryLogId()) {
queryDebuggingInfo.setResultSetLoggingData(resultLog);
XTableColumnModel columnModel = (XTableColumnModel)table.getColumnModel();
boolean isResultSetDataShown = columnModel.isColumnVisible(columnModel.getColumnByModelIndex(COLUMN_RS_LIFETIME));
if(isResultSetDataShown) {
updateRow(queryDebuggingInfo);
}
break;
}
}
}
};
if (isLogging) {
debugger.setLoggingListener(loggingListener);
} else {
}
else {
debugger.setLoggingListener(null);
}
}
class LoggerPaneLoggingListener implements LoggingListener {
private QueryMatcher[] matchers;
@Override
public QueryMatcher[] getMatchers() {
return matchers;
}
public void setMatchers(QueryMatcher[] matchers) {
this.matchers = matchers;
}
@Override
public void logQuery(QueryLog queryLog) {
debugQueries(new QueryDebuggingInfo(System.currentTimeMillis(), queryLog));
}
public void debugQueries(final QueryDebuggingInfo queryDebuggingInfo) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
debugQueries(queryDebuggingInfo);
}
});
return;
}
addRow(queryDebuggingInfo);
}
@Override
public void logResult(final ResultLog resultLog) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
logResult(resultLog);
}
});
return;
}
for (int i = queryDebuggingInfoList.size() - 1; i >= 0; i--) {
QueryDebuggingInfo queryDebuggingInfo = queryDebuggingInfoList.get(i);
if (queryDebuggingInfo.getQueryLoggingData().getID() == resultLog.getQueryLogId()) {
queryDebuggingInfo.setResultSetLoggingData(resultLog);
XTableColumnModel columnModel = (XTableColumnModel) table.getColumnModel();
boolean isResultSetDataShown = columnModel.isColumnVisible(columnModel.getColumnByModelIndex(COLUMN_RS_LIFETIME));
if (isResultSetDataShown) {
updateRow(queryDebuggingInfo);
}
break;
}
}
}
}
private void updateStatusLabel() {
int size = queryDebuggingInfoList.size();
int displayedCount = displayedQueryDebuggingInfoList.size();

View File

@ -55,29 +55,29 @@ import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import org.jooq.tools.debug.QueryType;
import org.jooq.tools.debug.QueryMatcher;
import org.jooq.tools.debug.QueryType;
import org.jooq.tools.debug.TextMatcher;
/**
* @author Christopher Deckers
*/
@SuppressWarnings("serial")
public class StatementMatcherPane extends JPanel {
public class QueryMatcherPane extends JPanel {
private JCheckBox activeCheckBox;
private JCheckBox threadNameTextMatcherCheckBox;
private TextMatcherPane threadNameTextMatcherPane;
private JCheckBox statementTextMatcherCheckBox;
private TextMatcherPane statementTextMatcherPane;
private JCheckBox statementTypeCheckBox;
private JCheckBox statementTypeSelectCheckBox;
private JCheckBox statementTypeUpdateCheckBox;
private JCheckBox statementTypeInsertCheckBox;
private JCheckBox statementTypeDeleteCheckBox;
private JCheckBox statementTypeOtherCheckBox;
private JCheckBox queryTextMatcherCheckBox;
private TextMatcherPane queryTextMatcherPane;
private JCheckBox queryTypeCheckBox;
private JCheckBox queryTypeSelectCheckBox;
private JCheckBox queryTypeUpdateCheckBox;
private JCheckBox queryTypeInsertCheckBox;
private JCheckBox queryTypeDeleteCheckBox;
private JCheckBox queryTypeOtherCheckBox;
public StatementMatcherPane(final StatementMatchersPane statementMatchersPane, QueryMatcher queryMatcher) {
public QueryMatcherPane(final QueryMatchersPane queryMatchersPane, QueryMatcher queryMatcher) {
super(new GridBagLayout());
setBorder(BorderFactory.createLineBorder(getBackground().darker()));
if(queryMatcher == null) {
@ -100,45 +100,45 @@ public class StatementMatcherPane extends JPanel {
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
statementMatchersPane.removeStatementMatcherPane(StatementMatcherPane.this);
queryMatchersPane.removeQueryMatcherPane(QueryMatcherPane.this);
}
});
closeButtonPane.add(closeButton);
northPane.add(closeButtonPane, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
add(northPane, new GridBagConstraints(0, y, 2, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
y++;
TextMatcher statementTextMatcher = queryMatcher.getStatementTextMatcher();
statementTextMatcherCheckBox = new JCheckBox("Statement", statementTextMatcher != null);
statementTextMatcherCheckBox.addItemListener(new ItemListener() {
TextMatcher queryTextMatcher = queryMatcher.getQueryTextMatcher();
queryTextMatcherCheckBox = new JCheckBox("Query", queryTextMatcher != null);
queryTextMatcherCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
adjustStates();
}
});
add(statementTextMatcherCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
statementTextMatcherPane = new TextMatcherPane(statementTextMatcher);
add(statementTextMatcherPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 0), 0, 0));
add(queryTextMatcherCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
queryTextMatcherPane = new TextMatcherPane(queryTextMatcher);
add(queryTextMatcherPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 0, 0), 0, 0));
y++;
Set<QueryType> queryTypeSet = queryMatcher.getQueryTypeSet();
statementTypeCheckBox = new JCheckBox("Type", queryTypeSet != null);
statementTypeCheckBox.addItemListener(new ItemListener() {
queryTypeCheckBox = new JCheckBox("Type", queryTypeSet != null);
queryTypeCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
adjustStates();
}
});
add(statementTypeCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
add(queryTypeCheckBox, new GridBagConstraints(0, y, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
JPanel typesPane = new JPanel(new GridBagLayout());
statementTypeSelectCheckBox = new JCheckBox("SELECT", queryTypeSet != null && queryTypeSet.contains(QueryType.SELECT));
typesPane.add(statementTypeSelectCheckBox, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
statementTypeUpdateCheckBox = new JCheckBox("UPDATE", queryTypeSet != null && queryTypeSet.contains(QueryType.UPDATE));
typesPane.add(statementTypeUpdateCheckBox, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
statementTypeInsertCheckBox = new JCheckBox("INSERT", queryTypeSet != null && queryTypeSet.contains(QueryType.INSERT));
typesPane.add(statementTypeInsertCheckBox, new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
statementTypeDeleteCheckBox = new JCheckBox("DELETE", queryTypeSet != null && queryTypeSet.contains(QueryType.DELETE));
typesPane.add(statementTypeDeleteCheckBox, new GridBagConstraints(3, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
statementTypeOtherCheckBox = new JCheckBox("OTHER", queryTypeSet != null && queryTypeSet.contains(QueryType.OTHER));
typesPane.add(statementTypeOtherCheckBox, new GridBagConstraints(4, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
queryTypeSelectCheckBox = new JCheckBox("SELECT", queryTypeSet != null && queryTypeSet.contains(QueryType.SELECT));
typesPane.add(queryTypeSelectCheckBox, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
queryTypeUpdateCheckBox = new JCheckBox("UPDATE", queryTypeSet != null && queryTypeSet.contains(QueryType.UPDATE));
typesPane.add(queryTypeUpdateCheckBox, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
queryTypeInsertCheckBox = new JCheckBox("INSERT", queryTypeSet != null && queryTypeSet.contains(QueryType.INSERT));
typesPane.add(queryTypeInsertCheckBox, new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
queryTypeDeleteCheckBox = new JCheckBox("DELETE", queryTypeSet != null && queryTypeSet.contains(QueryType.DELETE));
typesPane.add(queryTypeDeleteCheckBox, new GridBagConstraints(3, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
queryTypeOtherCheckBox = new JCheckBox("OTHER", queryTypeSet != null && queryTypeSet.contains(QueryType.OTHER));
typesPane.add(queryTypeOtherCheckBox, new GridBagConstraints(4, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 0, 0), 0, 0));
add(typesPane, new GridBagConstraints(1, y, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
y++;
TextMatcher threadNameTextMatcher = queryMatcher.getThreadNameTextMatcher();
@ -157,45 +157,45 @@ public class StatementMatcherPane extends JPanel {
private void adjustStates() {
boolean isActive = activeCheckBox.isSelected();
statementTextMatcherCheckBox.setEnabled(isActive);
statementTypeCheckBox.setEnabled(isActive);
queryTextMatcherCheckBox.setEnabled(isActive);
queryTypeCheckBox.setEnabled(isActive);
threadNameTextMatcherCheckBox.setEnabled(isActive);
statementTextMatcherPane.setLocked(!isActive || !statementTextMatcherCheckBox.isSelected());
statementTypeSelectCheckBox.setEnabled(isActive && statementTypeCheckBox.isSelected());
statementTypeUpdateCheckBox.setEnabled(isActive && statementTypeCheckBox.isSelected());
statementTypeInsertCheckBox.setEnabled(isActive && statementTypeCheckBox.isSelected());
statementTypeDeleteCheckBox.setEnabled(isActive && statementTypeCheckBox.isSelected());
statementTypeOtherCheckBox.setEnabled(isActive && statementTypeCheckBox.isSelected());
queryTextMatcherPane.setLocked(!isActive || !queryTextMatcherCheckBox.isSelected());
queryTypeSelectCheckBox.setEnabled(isActive && queryTypeCheckBox.isSelected());
queryTypeUpdateCheckBox.setEnabled(isActive && queryTypeCheckBox.isSelected());
queryTypeInsertCheckBox.setEnabled(isActive && queryTypeCheckBox.isSelected());
queryTypeDeleteCheckBox.setEnabled(isActive && queryTypeCheckBox.isSelected());
queryTypeOtherCheckBox.setEnabled(isActive && queryTypeCheckBox.isSelected());
threadNameTextMatcherPane.setLocked(!isActive || !threadNameTextMatcherCheckBox.isSelected());
}
public QueryMatcher getStatementMatcher() {
public QueryMatcher getQueryMatcher() {
boolean isActive = activeCheckBox.isSelected();
TextMatcher threadNameTextMatcher = threadNameTextMatcherCheckBox.isSelected()? threadNameTextMatcherPane.getTextMatcher(): null;
TextMatcher statementTextMatcher = statementTextMatcherCheckBox.isSelected()? statementTextMatcherPane.getTextMatcher(): null;
TextMatcher queryTextMatcher = queryTextMatcherCheckBox.isSelected()? queryTextMatcherPane.getTextMatcher(): null;
Set<QueryType> queryTypeSet;
if(statementTypeCheckBox.isSelected()) {
if(queryTypeCheckBox.isSelected()) {
List<QueryType> typeList = new ArrayList<QueryType>();
if(statementTypeSelectCheckBox.isSelected()) {
if(queryTypeSelectCheckBox.isSelected()) {
typeList.add(QueryType.SELECT);
}
if(statementTypeUpdateCheckBox.isSelected()) {
if(queryTypeUpdateCheckBox.isSelected()) {
typeList.add(QueryType.UPDATE);
}
if(statementTypeInsertCheckBox.isSelected()) {
if(queryTypeInsertCheckBox.isSelected()) {
typeList.add(QueryType.INSERT);
}
if(statementTypeDeleteCheckBox.isSelected()) {
if(queryTypeDeleteCheckBox.isSelected()) {
typeList.add(QueryType.DELETE);
}
if(statementTypeOtherCheckBox.isSelected()) {
if(queryTypeOtherCheckBox.isSelected()) {
typeList.add(QueryType.OTHER);
}
queryTypeSet = EnumSet.copyOf(typeList);
} else {
queryTypeSet = null;
}
return new QueryMatcher(threadNameTextMatcher, statementTextMatcher, queryTypeSet, isActive);
return new QueryMatcher(threadNameTextMatcher, queryTextMatcher, queryTypeSet, isActive);
}
}

View File

@ -50,26 +50,27 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.jooq.debug.console.LoggerPane.LoggerPaneLoggingListener;
import org.jooq.tools.debug.Debugger;
import org.jooq.tools.debug.QueryMatcher;
/**
* @author Christopher Deckers
*/
@SuppressWarnings("serial")
public class StatementMatchersDialogBox extends JDialog {
public class QueryMatchersDialogBox extends JDialog {
public QueryMatchersDialogBox(Component parent, final Debugger debugger, final LoggerPaneLoggingListener listener) {
super(SwingUtilities.getWindowAncestor(parent), "Query filters", ModalityType.DOCUMENT_MODAL);
public StatementMatchersDialogBox(Component parent, final Debugger debugger) {
super(SwingUtilities.getWindowAncestor(parent), "Statement filters", ModalityType.DOCUMENT_MODAL);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Container contentPane = getContentPane();
JPanel northPane = new JPanel(new BorderLayout());
northPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 2, 5));
northPane.add(new JLabel("Log statements matching any of these filters:"), BorderLayout.WEST);
northPane.add(new JLabel("Log queries matching any of these filters:"), BorderLayout.WEST);
contentPane.add(northPane, BorderLayout.NORTH);
final StatementMatchersPane statementMatchersPane = new StatementMatchersPane(debugger.getLoggingStatementMatchers());
statementMatchersPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
contentPane.add(statementMatchersPane, BorderLayout.CENTER);
final QueryMatchersPane matchersPane = new QueryMatchersPane(listener.getMatchers());
matchersPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
contentPane.add(matchersPane, BorderLayout.CENTER);
JPanel buttonBar = new JPanel(new BorderLayout());
buttonBar.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel filterButtonsPane = new JPanel(new GridLayout(1, 2, 2, 0));
@ -77,7 +78,7 @@ public class StatementMatchersDialogBox extends JDialog {
addFilterButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
statementMatchersPane.addStatementMatcherPane(new StatementMatcherPane(statementMatchersPane, null));
matchersPane.addQueryMatcherPane(new QueryMatcherPane(matchersPane, null));
}
});
filterButtonsPane.add(addFilterButton);
@ -85,7 +86,7 @@ public class StatementMatchersDialogBox extends JDialog {
removeAllFiltersButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
statementMatchersPane.removeAllStatementMatcherPanes();
matchersPane.removeAllQueryMatcherPanes();
}
});
filterButtonsPane.add(removeAllFiltersButton);
@ -95,8 +96,8 @@ public class StatementMatchersDialogBox extends JDialog {
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
QueryMatcher[] statementMatchers = statementMatchersPane.getStatementMatchers();
debugger.setLoggingStatementMatchers(statementMatchers.length == 0? null: statementMatchers);
listener.setMatchers(matchersPane.getMatchers());
debugger.setLoggingListener(listener);
dispose();
}
});
@ -105,8 +106,8 @@ public class StatementMatchersDialogBox extends JDialog {
applyButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
QueryMatcher[] statementMatchers = statementMatchersPane.getStatementMatchers();
debugger.setLoggingStatementMatchers(statementMatchers.length == 0? null: statementMatchers);
listener.setMatchers(matchersPane.getMatchers());
debugger.setLoggingListener(listener);
}
});
rightButtonsPane.add(applyButton);

View File

@ -55,7 +55,7 @@ import org.jooq.tools.debug.QueryMatcher;
* @author Christopher Deckers
*/
@SuppressWarnings("serial")
public class StatementMatchersPane extends JPanel {
public class QueryMatchersPane extends JPanel {
private static class ScrollablePane extends JPanel implements Scrollable {
@ -90,63 +90,62 @@ public class StatementMatchersPane extends JPanel {
}
private JPanel statementMatcherPanesContainer;
private JPanel matcherPanesContainer;
public StatementMatchersPane(QueryMatcher[] statementMatchers) {
public QueryMatchersPane(QueryMatcher[] matchers) {
super(new BorderLayout());
statementMatcherPanesContainer = new ScrollablePane();
statementMatcherPanesContainer.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
matcherPanesContainer = new ScrollablePane();
matcherPanesContainer.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
addDefaultMessageComponent();
add(new JScrollPane(statementMatcherPanesContainer), BorderLayout.CENTER);
if(statementMatchers != null) {
for(QueryMatcher queryMatcher: statementMatchers) {
addStatementMatcherPane(new StatementMatcherPane(this, queryMatcher));
add(new JScrollPane(matcherPanesContainer), BorderLayout.CENTER);
if (matchers != null) {
for (QueryMatcher matcher : matchers) {
addQueryMatcherPane(new QueryMatcherPane(this, matcher));
}
}
}
public void addStatementMatcherPane(StatementMatcherPane statementMatcherPane) {
if(!(statementMatcherPanesContainer.getComponent(0) instanceof StatementMatcherPane)) {
statementMatcherPanesContainer.remove(0);
public void addQueryMatcherPane(QueryMatcherPane pane) {
if(!(matcherPanesContainer.getComponent(0) instanceof QueryMatcherPane)) {
matcherPanesContainer.remove(0);
}
statementMatcherPanesContainer.add(statementMatcherPane);
statementMatcherPanesContainer.revalidate();
statementMatcherPanesContainer.repaint();
statementMatcherPanesContainer.scrollRectToVisible(new Rectangle(0, Short.MAX_VALUE, 1, 1));
matcherPanesContainer.add(pane);
matcherPanesContainer.revalidate();
matcherPanesContainer.repaint();
matcherPanesContainer.scrollRectToVisible(new Rectangle(0, Short.MAX_VALUE, 1, 1));
}
void removeAllStatementMatcherPanes() {
statementMatcherPanesContainer.removeAll();
void removeAllQueryMatcherPanes() {
matcherPanesContainer.removeAll();
addDefaultMessageComponent();
statementMatcherPanesContainer.revalidate();
statementMatcherPanesContainer.repaint();
matcherPanesContainer.revalidate();
matcherPanesContainer.repaint();
}
private void addDefaultMessageComponent() {
JLabel messageLabel = new JLabel("No statement filters, logging everything.");
JLabel messageLabel = new JLabel("No query filters, logging everything.");
messageLabel.setFont(messageLabel.getFont().deriveFont(Font.ITALIC));
statementMatcherPanesContainer.add(messageLabel);
matcherPanesContainer.add(messageLabel);
}
void removeStatementMatcherPane(StatementMatcherPane statementMatcherPane) {
statementMatcherPanesContainer.remove(statementMatcherPane);
if(statementMatcherPanesContainer.getComponentCount() == 0) {
void removeQueryMatcherPane(QueryMatcherPane pane) {
matcherPanesContainer.remove(pane);
if (matcherPanesContainer.getComponentCount() == 0) {
addDefaultMessageComponent();
}
statementMatcherPanesContainer.revalidate();
statementMatcherPanesContainer.repaint();
matcherPanesContainer.revalidate();
matcherPanesContainer.repaint();
}
public QueryMatcher[] getStatementMatchers() {
if(!(statementMatcherPanesContainer.getComponent(0) instanceof StatementMatcherPane)) {
public QueryMatcher[] getMatchers() {
if (!(matcherPanesContainer.getComponent(0) instanceof QueryMatcherPane)) {
return new QueryMatcher[0];
}
Component[] components = statementMatcherPanesContainer.getComponents();
QueryMatcher[] statementMatchers = new QueryMatcher[components.length];
for(int i=0; i<components.length; i++) {
statementMatchers[i] = ((StatementMatcherPane)components[i]).getStatementMatcher();
Component[] components = matcherPanesContainer.getComponents();
QueryMatcher[] matchers = new QueryMatcher[components.length];
for (int i = 0; i < components.length; i++) {
matchers[i] = ((QueryMatcherPane) components[i]).getQueryMatcher();
}
return statementMatchers;
return matchers;
}
}

View File

@ -56,14 +56,14 @@ import org.fife.ui.rtextarea.RTextScrollPane;
* @author Christopher Deckers
*/
@SuppressWarnings("serial")
public class StatementProcessorPane extends JPanel {
public class QueryProcessorPane extends JPanel {
private JComboBox processorTypeComboBox;
private JTextField processorTextField;
private JScrollPane processorStaticScrollPane;
private SqlTextArea processorStaticSQLTextArea;
public StatementProcessorPane(QueryProcessor queryProcessor) {
public QueryProcessorPane(QueryProcessor queryProcessor) {
super(new GridBagLayout());
setOpaque(false);
if(queryProcessor == null) {
@ -100,7 +100,7 @@ public class StatementProcessorPane extends JPanel {
repaint();
}
public QueryProcessor getStatementProcessor() {
public QueryProcessor getQueryProcessor() {
QueryProcessor.ProcessorExecutionType type = (QueryProcessor.ProcessorExecutionType)processorTypeComboBox.getSelectedItem();
return new QueryProcessor(type, type == QueryProcessor.ProcessorExecutionType.STATIC? processorStaticSQLTextArea.getText(): processorTextField.getText());
}

View File

@ -37,24 +37,37 @@
package org.jooq.tools.debug;
import org.jooq.ExecuteContext;
import org.jooq.Query;
import org.jooq.Result;
import org.jooq.tools.debug.impl.DebuggerFactory;
/**
* The jOOQ debugger API
* <p>
* This is the main API for hooking into jOOQ's debugging capabilities locally
* or remotely. In order to create a <code>Debugger</code> instance, use
* {@link DebuggerFactory#localDebugger(DatabaseDescriptor)} or
* {@link DebuggerFactory#remoteDebugger(String, int)}
*
* @author Christopher Deckers
* @author Lukas Eder
*/
public interface Debugger extends QueryExecutorCreator {
/**
* Set a logging listener to the <code>Debugger</code>
* <p>
* Logging listeners log {@link Query} and {@link Result} objects.
*
* @param listener a listener, or null to stop logging.
*/
public void setLoggingListener(LoggingListener listener);
/**
* Get the <code>Debugger</code>'s configured logging listeners
*/
public LoggingListener getLoggingListener();
public void setLoggingStatementMatchers(QueryMatcher[] matchers);
public QueryMatcher[] getLoggingStatementMatchers();
public void setBreakpoints(Breakpoint[] breakpoints);
public void addBreakpoint(Breakpoint breakpoint);

View File

@ -46,17 +46,30 @@ import org.jooq.Result;
* notifications about executed queries and fetched results.
*
* @author Christopher Deckers
* @author Lukas Eder
*/
public interface LoggingListener {
/**
* Get the matchers used for this listener
* <p>
* A logging listener's matchers are used to check whether queries should be
* logged for this listener. The resulting array is expected to be
* "immutable", i.e. the jOOQ debug API may cache its value. If a listener's
* associated {@link QueryMatcher} array changes, set the listener onto the
* debugger afresh, using
* {@link Debugger#setLoggingListener(LoggingListener)}
*/
QueryMatcher[] getMatchers();
/**
* Notification that a {@link Query} has been executed.
*/
public void logQuery(QueryLog log);
void logQuery(QueryLog log);
/**
* Notification that a {@link Result} has been fetched.
*/
public void logResult(ResultLog log);
void logResult(ResultLog log);
}

View File

@ -49,17 +49,19 @@ public class QueryMatcher implements Serializable {
private boolean isActive;
private TextMatcher threadNameTextMatcher;
private TextMatcher statementTextMatcher;
private TextMatcher queryTextMatcher;
private Set<QueryType> queryTypeSet;
/**
* @param threadNameTextMatcher a text matcher for thread name or null for no text matching.
* @param statementTextMatcher a text matcher for statement or null for no text matching.
* @param threadNameTextMatcher a text matcher for thread name or null for
* no text matching.
* @param queryTextMatcher a text matcher for statement or null for no text
* matching.
* @param queryTypeSet some types or null for all types.
*/
public QueryMatcher(TextMatcher threadNameTextMatcher, TextMatcher statementTextMatcher, Set<QueryType> queryTypeSet, boolean isActive) {
public QueryMatcher(TextMatcher threadNameTextMatcher, TextMatcher queryTextMatcher, Set<QueryType> queryTypeSet, boolean isActive) {
this.threadNameTextMatcher = threadNameTextMatcher;
this.statementTextMatcher = statementTextMatcher;
this.queryTextMatcher = queryTextMatcher;
this.queryTypeSet = queryTypeSet == null? null: EnumSet.copyOf(queryTypeSet);
this.isActive = isActive;
}
@ -75,8 +77,8 @@ public class QueryMatcher implements Serializable {
}
hasMatcher = true;
}
if (statementTextMatcher != null) {
if (!statementTextMatcher.matches(queryInfo.getQueries())) {
if (queryTextMatcher != null) {
if (!queryTextMatcher.matches(queryInfo.getQueries())) {
return false;
}
hasMatcher = true;
@ -94,8 +96,8 @@ public class QueryMatcher implements Serializable {
return threadNameTextMatcher;
}
public TextMatcher getStatementTextMatcher() {
return statementTextMatcher;
public TextMatcher getQueryTextMatcher() {
return queryTextMatcher;
}
public Set<QueryType> getQueryTypeSet() {

View File

@ -50,7 +50,6 @@ import org.jooq.tools.debug.Debugger;
import org.jooq.tools.debug.LoggingListener;
import org.jooq.tools.debug.QueryExecutor;
import org.jooq.tools.debug.QueryLog;
import org.jooq.tools.debug.QueryMatcher;
import org.jooq.tools.debug.ResultLog;
import org.jooq.tools.debug.impl.ServerDebugger.CMS_addBreakpoint;
import org.jooq.tools.debug.impl.ServerDebugger.CMS_isExecutionSupported;
@ -59,7 +58,6 @@ import org.jooq.tools.debug.impl.ServerDebugger.CMS_removeBreakpoint;
import org.jooq.tools.debug.impl.ServerDebugger.CMS_setBreakpointHitHandlerActive;
import org.jooq.tools.debug.impl.ServerDebugger.CMS_setBreakpoints;
import org.jooq.tools.debug.impl.ServerDebugger.CMS_setLoggingActive;
import org.jooq.tools.debug.impl.ServerDebugger.CMS_setLoggingStatementMatchers;
/**
* @author Christopher Deckers
@ -84,14 +82,16 @@ class ClientDebugger implements Debugger {
private final Object LOGGING_LISTENER_LOCK = new Object();
@Override
public void setLoggingListener(LoggingListener loggingListener) {
public void setLoggingListener(LoggingListener listener) {
synchronized (LOGGING_LISTENER_LOCK) {
if(this.loggingListener == loggingListener) {
if(this.loggingListener == listener) {
return;
}
this.loggingListener = loggingListener;
this.loggingListener = listener;
}
comm.asyncSend((CommandMessage<?>) new CMS_setLoggingActive(loggingListener != null));
comm.asyncSend((CommandMessage<?>) new CMS_setLoggingActive(
listener != null,
listener != null ? listener.getMatchers() : null));
}
@Override
@ -101,24 +101,6 @@ class ClientDebugger implements Debugger {
}
}
private QueryMatcher[] loggingStatementMatchers;
private final Object LOGGING_STATEMENT_MATCHERS_LOCK = new Object();
@Override
public void setLoggingStatementMatchers(QueryMatcher[] matchers) {
synchronized (LOGGING_STATEMENT_MATCHERS_LOCK) {
this.loggingStatementMatchers = matchers;
}
comm.asyncSend((CommandMessage<?>) new CMS_setLoggingStatementMatchers(matchers));
}
@Override
public QueryMatcher[] getLoggingStatementMatchers() {
synchronized (LOGGING_STATEMENT_MATCHERS_LOCK) {
return loggingStatementMatchers;
}
}
private Breakpoint[] breakpoints;
private final Object BREAKPOINT_LOCK = new Object();

View File

@ -188,20 +188,26 @@ public class DebugListener extends DefaultExecuteListener {
long subStartExecutionTime = System.currentTimeMillis();
executeSQL(ctx, sql);
long subEndExecutionTime = System.currentTimeMillis();
// Log result of pre-processing.
for(Debugger debugger: debuggerList) {
LoggingListener loggingListener = debugger.getLoggingListener();
if(loggingListener != null) {
QueryType queryType = QueryType.detectType(sql);
QueryInfo queryInfo = new QueryInfo(queryType, new String[] {sql}, null);
QueryLog queryLog = new QueryLog(queryInfo, null, null, subEndExecutionTime - subStartExecutionTime);
QueryMatcher[] loggingStatementMatchers = debugger.getLoggingStatementMatchers();
if(loggingStatementMatchers == null) {
loggingListener.logQuery(queryLog);
} else for(QueryMatcher queryMatcher: loggingStatementMatchers) {
if(queryMatcher.matches(queryLog.getQueryInfo())) {
loggingListener.logQuery(queryLog);
break;
for (Debugger debugger : debuggerList) {
LoggingListener listener = debugger.getLoggingListener();
if (listener != null) {
QueryType type = QueryType.detectType(sql);
QueryInfo info = new QueryInfo(type, new String[] { sql }, null);
QueryLog log = new QueryLog(info, null, null, subEndExecutionTime - subStartExecutionTime);
QueryMatcher[] matchers = listener.getMatchers();
if (matchers == null) {
listener.logQuery(log);
}
else {
for (QueryMatcher matcher : matchers) {
if (matcher.matches(log.getQueryInfo())) {
listener.logQuery(log);
break;
}
}
}
}
@ -304,61 +310,66 @@ public class DebugListener extends DefaultExecuteListener {
return;
}
endExecutionTime = System.currentTimeMillis();
List<Debugger> debuggerList = DebuggerRegistry.get();
if(!debuggerList.isEmpty()) {
List<Debugger> debuggers = DebuggerRegistry.get();
if(!debuggers.isEmpty()) {
boolean hasListener = false;
for(Debugger debugger: debuggerList) {
LoggingListener loggingListener = debugger.getLoggingListener();
if(loggingListener != null) {
hasListener = true;
break;
}
}
for (Debugger debugger : debuggers) {
LoggingListener listener = debugger.getLoggingListener();
if (listener != null) {
hasListener = true;
break;
}
}
if(hasListener) {
String[] sql = ctx.batchSQL();
QueryType queryType = QueryType.detectType(sql[0]);
String parameterDescription = null;
if(sql.length == 1) {
PreparedStatement statement = ctx.statement();
if(statement instanceof TrackingPreparedStatement) {
parameterDescription = ((TrackingPreparedStatement) statement).getParameterDescription();
}
}
QueryInfo queryInfo = new QueryInfo(queryType, sql, parameterDescription);
final QueryLog queryLog = new QueryLog(queryInfo, startPreparationTime == 0? null: aggregatedPreparationDuration, startBindTime == 0? null: endBindTime - startBindTime, endExecutionTime - startExecutionTime);
final List<LoggingListener> loggingListenerList = new ArrayList<LoggingListener>(debuggerList.size());
for(Debugger listener: debuggerList) {
LoggingListener loggingListener = listener.getLoggingListener();
if(loggingListener != null) {
QueryMatcher[] loggingStatementMatchers = listener.getLoggingStatementMatchers();
if(loggingStatementMatchers == null) {
loggingListenerList.add(loggingListener);
loggingListener.logQuery(queryLog);
} else for(QueryMatcher queryMatcher: loggingStatementMatchers) {
if(queryMatcher.matches(queryLog.getQueryInfo())) {
loggingListenerList.add(loggingListener);
loggingListener.logQuery(queryLog);
break;
}
}
}
QueryType type = QueryType.detectType(sql[0]);
String parameterDescription = null;
if (sql.length == 1) {
PreparedStatement statement = ctx.statement();
if (statement instanceof TrackingPreparedStatement) {
parameterDescription = ((TrackingPreparedStatement) statement).getParameterDescription();
}
}
QueryInfo info = new QueryInfo(type, sql, parameterDescription);
final QueryLog log = new QueryLog(info, startPreparationTime == 0? null: aggregatedPreparationDuration, startBindTime == 0? null: endBindTime - startBindTime, endExecutionTime - startExecutionTime);
final List<LoggingListener> listeners = new ArrayList<LoggingListener>(debuggers.size());
for (Debugger debugger : debuggers) {
LoggingListener listener = debugger.getLoggingListener();
if (listener != null) {
QueryMatcher[] matchers = listener.getMatchers();
if (matchers == null) {
listeners.add(listener);
listener.logQuery(log);
}
else {
for (QueryMatcher matcher : matchers) {
if (matcher.matches(log.getQueryInfo())) {
listeners.add(listener);
listener.logQuery(log);
break;
}
}
}
}
}
ResultSet resultSet = ctx.resultSet();
if(resultSet != null && !loggingListenerList.isEmpty()) {
ResultSet newResultSet = new TrackingResultSet(resultSet) {
@Override
protected void notifyData(long lifeTime, int readRows, int readCount, int writeCount) {
ResultLog resultLog = null;
for(LoggingListener loggingListener: loggingListenerList) {
if(resultLog == null) {
resultLog = new ResultLog(queryLog.getID(), lifeTime, readRows, readCount, writeCount);
}
loggingListener.logResult(resultLog);
}
}
};
ctx.resultSet(newResultSet);
}
if (resultSet != null && !listeners.isEmpty()) {
ResultSet newResultSet = new TrackingResultSet(resultSet) {
@Override
protected void notifyData(long lifeTime, int readRows, int readCount, int writeCount) {
ResultLog resultLog = null;
for (LoggingListener loggingListener : listeners) {
if (resultLog == null) {
resultLog = new ResultLog(log.getID(), lifeTime, readRows, readCount, writeCount);
}
loggingListener.logResult(resultLog);
}
}
};
ctx.resultSet(newResultSet);
}
}
}
if(matchingDebugger != null) {
@ -378,19 +389,24 @@ public class DebugListener extends DefaultExecuteListener {
executeSQL(ctx, sql);
long subEndExecutionTime = System.currentTimeMillis();
// Log result of pre-processing.
for(Debugger listener: debuggerList) {
LoggingListener loggingListener = listener.getLoggingListener();
if(loggingListener != null) {
QueryType queryType = QueryType.detectType(sql);
QueryInfo queryInfo = new QueryInfo(queryType, new String[] {sql}, null);
QueryLog queryLog = new QueryLog(queryInfo, null, null, subEndExecutionTime - subStartExecutionTime);
QueryMatcher[] loggingStatementMatchers = listener.getLoggingStatementMatchers();
if(loggingStatementMatchers == null) {
loggingListener.logQuery(queryLog);
} else for(QueryMatcher queryMatcher: loggingStatementMatchers) {
if(queryMatcher.matches(queryLog.getQueryInfo())) {
loggingListener.logQuery(queryLog);
break;
for (Debugger debugger : debuggers) {
LoggingListener listener = debugger.getLoggingListener();
if (listener != null) {
QueryType type = QueryType.detectType(sql);
QueryInfo info = new QueryInfo(type, new String[] {sql}, null);
QueryLog log = new QueryLog(info, null, null, subEndExecutionTime - subStartExecutionTime);
QueryMatcher[] matchers = listener.getMatchers();
if (matchers == null) {
listener.logQuery(log);
}
else {
for (QueryMatcher matcher : matchers) {
if (matcher.matches(log.getQueryInfo())) {
listener.logQuery(log);
break;
}
}
}
}

View File

@ -58,7 +58,6 @@ import org.jooq.tools.debug.DatabaseDescriptor;
import org.jooq.tools.debug.Debugger;
import org.jooq.tools.debug.LoggingListener;
import org.jooq.tools.debug.QueryExecutorContext;
import org.jooq.tools.debug.QueryMatcher;
/**
@ -95,23 +94,6 @@ class LocalDebugger implements Debugger {
}
}
private QueryMatcher[] loggingStatementMatchers;
private final Object LOGGING_STATEMENT_MATCHERS_LOCK = new Object();
@Override
public void setLoggingStatementMatchers(QueryMatcher[] loggingStatementMatchers) {
synchronized (LOGGING_STATEMENT_MATCHERS_LOCK) {
this.loggingStatementMatchers = loggingStatementMatchers;
}
}
@Override
public QueryMatcher[] getLoggingStatementMatchers() {
synchronized (LOGGING_STATEMENT_MATCHERS_LOCK) {
return loggingStatementMatchers;
}
}
private Breakpoint[] breakpoints;
private final Object BREAKPOINT_LOCK = new Object();

View File

@ -73,33 +73,43 @@ class ServerDebugger extends LocalDebugger {
this.comm = communication;
}
private void setLoggingActive(boolean isActive) {
if(isActive) {
private void setLoggingActive(boolean isActive, final QueryMatcher[] matchers) {
if (isActive) {
setLoggingListener(new LoggingListener() {
@Override
public QueryMatcher[] getMatchers() {
return matchers;
}
@Override
public void logQuery(QueryLog queryLog) {
comm.asyncSend((CommandMessage<?>) new CMC_logQueries(queryLog));
}
@Override
public void logResult(ResultLog resultLog) {
comm.asyncSend((CommandMessage<?>) new CMC_logResultSet(resultLog));
}
});
} else {
}
else {
setLoggingListener(null);
}
}
static class CMS_setLoggingActive extends CommandMessage<Serializable> {
private final boolean isActive;
private final QueryMatcher[] matchers;
CMS_setLoggingActive(boolean isActive) {
CMS_setLoggingActive(boolean isActive, QueryMatcher[] matchers) {
this.isActive = isActive;
this.matchers = matchers;
}
@Override
public Serializable run(MessageContext context) {
getServerDebugger(context).setLoggingActive(isActive);
getServerDebugger(context).setLoggingActive(isActive, matchers);
return null;
}
}
@ -124,20 +134,6 @@ class ServerDebugger extends LocalDebugger {
}
}
static class CMS_setLoggingStatementMatchers extends CommandMessage<Serializable> {
private final QueryMatcher[] matchers;
CMS_setLoggingStatementMatchers(QueryMatcher[] matchers) {
this.matchers = matchers;
}
@Override
public Serializable run(MessageContext context) {
context.getDebugger().setLoggingStatementMatchers(matchers);
return null;
}
}
static class CMS_setBreakpoints extends CommandMessage<Serializable> {
private final Breakpoint[] breakpoints;