Thursday, December 24, 2009

Step Back Debugging for Java in Eclipse?

In debugging, there are "step into", "step over" etc., but what about a "step back" feature? There are chances that when you hit a "step over" twice by mistake, or when you find out it might be just the previous line which is causing trouble, you just want a "roll back" feature.

Debugging is like traversal on a tree or on a graph. Every breakpoint is a state or a node. In theory, if we save these states, we can step back and forth among any of them. Snapshot, versioning or savepoint can be useful in helping save the debugging states.

There are already such support in C/C++ debuggers like gdb. However, it seems that no Java debugger supports "step back" or "roll back". It would be even nicer if such feature could be included in Eclipse IDE.

Wednesday, December 16, 2009

Apache: Full Long File Names in Index

There are cases that the default index file in Apache server trimmed your long file name. Instead you'd like to show them in full length. To do this, you can edit the configuration file of your Apache server (httpd.conf). Add "NameWidth=*" to IndexOptions, so that it looks like:

IndexOptions FancyIndexing NameWidth=*

Reference
http://httpd.apache.org/docs/1.3/mod/mod_autoindex.html#indexoptions

Saturday, December 12, 2009

SQL: a Cross-Tabular Report with Case, Rollup and Grouping Functions

A Cross-Tabular Report is widely used in computer software. If you keep a journal of expenses, for instance, and by the end of year, you would like to review how much you have spent on each type of goods in a month-by-month view. Or a website administrator would like to know, for each page or URL of website, how many visitors visited using different browsers. These are cases when you need a cross-tabular report. (Definitions of Cross Tabulation or Contingency table.)

So how to generate a cross tab report in just one line of SQL? The idea is to split columns with "CASE" and group rows with "GROUP BY ROLLUP(name)" and decorate the result with "DECODE(GROUPING(name), 1, 'Total', name)".

Here's an Example:

We have a log table:

SQL> select page "Page", brws_type "Browser" from visit_table;

Page            Browser
--------------- ----------
index.htm       FF
index.htm       IE
index.htm       IE
page1.htm       FF
page2.htm       FF
page3.htm       FF
about.htm       FF
about.htm       SF
index.htm       SF
index.htm       SF
index.htm       FF

Page            Browser
--------------- ----------
page2.htm       IE
page2.htm       IE
contact.htm     IE
contact.htm     SF
page3.htm       SF


And now comes the query for cross-tabular report.

SQL> SELECT DECODE(GROUPING(page), 1, 'All pages', page) "Pages",
            COUNT(CASE WHEN brws_type='FF' THEN 1 ELSE null END) "Firefox",
            COUNT(CASE WHEN brws_type='IE' THEN 1 ELSE null END) "Internet Explorer",
            COUNT(CASE WHEN brws_type='SF' THEN 1 ELSE null END) "Safari",
            COUNT(*) count
      FROM visit_table
      WHERE 1=1
      GROUP BY ROLLUP(page)
      ORDER BY count desc;
Pages              Firefox Internet Explorer     Safari      COUNT
--------------- ---------- ----------------- ---------- ----------
All pages                6                 5          5         16
index.htm                2                 2          2          6
page2.htm                1                 2          0          3
about.htm                1                 0          1          2
contact.htm              0                 1          1          2
page3.htm                1                 0          1          2
page1.htm                1                 0          0          1


SQL is a powerful language.