diff --git a/README.md b/README.md index 3809879..9dc7479 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Usage: FROM MY_TABLE EOF +If _mailSendTo_ configured the tool sends an email with formatted output. + ## Config values: * jdbcDriverPath=Path to jdbc driver jar (loaded dynamically) if null it must be in classpath @@ -19,8 +21,11 @@ Usage: * jdbcPass= * inputSQL=Path to input sql file (not required/optional if not present it uses stdin) * outputResult=Path to output file (if not present uses stdout) + +## Printing and formatting values: * printHeader=true/false If true adds header with query's column name. Default true * printFieldSeparator=Field separator for printing. Default tab (\t) +* formatterName=Formatter type, possible values: text, html or csv (default text) ## Mail config values: diff --git a/pom.xml b/pom.xml index 729ff4e..f7ee2e1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.jdlopez sqlcmd - 1.1 + 1.1.1 diff --git a/src/main/java/es/jdlopez/sqlcmd/CsvFormatter.java b/src/main/java/es/jdlopez/sqlcmd/CsvFormatter.java new file mode 100644 index 0000000..4c7b273 --- /dev/null +++ b/src/main/java/es/jdlopez/sqlcmd/CsvFormatter.java @@ -0,0 +1,59 @@ +package es.jdlopez.sqlcmd; + +import java.io.PrintWriter; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +public class CsvFormatter extends ResultFormatter { + private RunnerConfig conf; + + public CsvFormatter(RunnerConfig c) { + this.conf = c; + } + + @Override + public void writeHeader(PrintWriter out, ResultSetMetaData rsmd) throws SQLException { + int colCount = rsmd.getColumnCount(); + if (conf.getPrintHeader()) { + for (int i = 1; i <= colCount; i++) { + out.print(rsmd.getColumnName(i)); + if (i < colCount) { + out.print(conf.getPrintFieldSeparator()); + } + } + out.println(); + } // header + + } + + @Override + public void writeRow(PrintWriter out, ResultSet resultSet, int colCount) throws SQLException { + for (int i = 1; i <= colCount; i++) { + out.print(resultSet.getString(i)); + if (i < colCount) + out.print(conf.getPrintFieldSeparator()); + } // for col + out.println(); + } + + @Override + public void writeEndResultSet(PrintWriter out) { + // nothing needed + } + + @Override + public void writeBeginResultSet(PrintWriter out) { + // nothing needed + } + + @Override + public void writeUpdate(PrintWriter out, int updateCount) { + out.println(updateCount); + } + + @Override + public String getMime() { + return "text/csv"; + } +} diff --git a/src/main/java/es/jdlopez/sqlcmd/HtmlFormatter.java b/src/main/java/es/jdlopez/sqlcmd/HtmlFormatter.java new file mode 100644 index 0000000..ad1af98 --- /dev/null +++ b/src/main/java/es/jdlopez/sqlcmd/HtmlFormatter.java @@ -0,0 +1,57 @@ +package es.jdlopez.sqlcmd; + +import java.io.PrintWriter; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +// TODO: put all html code in configurable templates +public class HtmlFormatter extends ResultFormatter { + private RunnerConfig conf; + + public HtmlFormatter(RunnerConfig c) { + this.conf = c; + } + + @Override + public void writeHeader(PrintWriter out, ResultSetMetaData rsmd) throws SQLException { + if (conf.getPrintHeader()) { // this check must be on MainRunner :-( + int colCount = rsmd.getColumnCount(); + // add thead tag??? + out.println(""); + for (int i = 1; i <= colCount; i++) { + out.print(String.format("%s", rsmd.getColumnName(i))); + } + out.println(""); + } // header + } + + @Override + public void writeRow(PrintWriter out, ResultSet resultSet, int colCount) throws SQLException { + out.println(""); + for (int i = 1; i <= colCount; i++) { + out.print(String.format("%s", resultSet.getString(i))); + } // for col + out.println(""); + } + + @Override + public void writeBeginResultSet(PrintWriter out) { + out.println(""); + } + + @Override + public void writeEndResultSet(PrintWriter out) { + out.println("
"); + } + + @Override + public void writeUpdate(PrintWriter out, int updateCount) { + out.println(String.format("
UpdateCount: %d
", updateCount)); + } + + @Override + public String getMime() { + return "text/html"; + } +} diff --git a/src/main/java/es/jdlopez/sqlcmd/MainRunner.java b/src/main/java/es/jdlopez/sqlcmd/MainRunner.java index 5041921..2211cf3 100644 --- a/src/main/java/es/jdlopez/sqlcmd/MainRunner.java +++ b/src/main/java/es/jdlopez/sqlcmd/MainRunner.java @@ -10,7 +10,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.sql.Connection; -import java.sql.Driver; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; @@ -81,7 +80,11 @@ else if (config.getOutputResult() == null) config.getMailPort(), config.getMailFrom()); } - sendMail.sendText(config.getMailSubject(), mailBody.toString(), config.getMailSendTo()); + if (ResultFormatter.HTML.equalsIgnoreCase(config.getFormatterName())) + sendMail.sendMime(config.buildFormatter().getMime(), + config.getMailSubject(), mailBody.toString(), config.getMailSendTo()); + else // careful 'no object DCH for MIME type csv or others needs activation + sendMail.sendText(config.getMailSubject(), mailBody.toString(), config.getMailSendTo()); } } finally { @@ -91,44 +94,21 @@ else if (config.getOutputResult() == null) } private static void writeUpdateCount(int updateCount, PrintWriter out, RunnerConfig config) { - String s; - if (config.getPrintHeader()) - s = String.format("==================\nUpdateCount = %d\n==================", updateCount); - else - s = "UpdateCount = " + updateCount; - out.println(s); - + ResultFormatter fmt = config.buildFormatter(); + fmt.writeUpdate(out, updateCount); } private static void writeResultSet(ResultSet resultSet, PrintWriter out, RunnerConfig conf) throws SQLException { ResultSetMetaData rsmd = resultSet.getMetaData(); int colCount = rsmd.getColumnCount(); - if (conf.getPrintHeader()) { - StringBuffer underline = new StringBuffer(); - for (int i = 1; i <= colCount; i++) { - out.print(rsmd.getColumnName(i)); - underline.append(repeatChar('=', rsmd.getColumnName(i).length())); - if (i < colCount) { - out.print(conf.getPrintFieldSeparator()); - underline.append(conf.getPrintFieldSeparator()); - } - } - out.println(); - out.println(underline.toString()); - } // header + ResultFormatter fmt = conf.buildFormatter(); + fmt.writeBeginResultSet(out); + fmt.writeHeader(out, rsmd); while (resultSet.next()) { - for (int i = 1; i <= colCount; i++) { - out.print(resultSet.getString(i)); - if (i < colCount) - out.print(conf.getPrintFieldSeparator()); - } // for col - out.println(); + fmt.writeRow(out, resultSet, colCount); } // while row out.flush(); - } - - private static String repeatChar(char c, int length) { - return new String(new char[length]).replace('\0', c); + fmt.writeEndResultSet(out); } private static String readAll(InputStream in) throws IOException { @@ -169,6 +149,8 @@ private static RunnerConfig readArgs(String[] args) throws ConfigException { conf.setPrintFieldSeparator("\t"); if (conf.getPrintHeader() == null) conf.setPrintHeader(true); + if (conf.getFormatterName() == null) + conf.setFormatterName("text"); return conf; } } diff --git a/src/main/java/es/jdlopez/sqlcmd/ResultFormatter.java b/src/main/java/es/jdlopez/sqlcmd/ResultFormatter.java new file mode 100644 index 0000000..264e8e7 --- /dev/null +++ b/src/main/java/es/jdlopez/sqlcmd/ResultFormatter.java @@ -0,0 +1,30 @@ +package es.jdlopez.sqlcmd; + +import java.io.PrintWriter; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +public abstract class ResultFormatter { + + public static final String TEXT = "text"; + public static final String HTML = "html"; + public static final String CSV = "csv"; + + public abstract void writeHeader(PrintWriter out, ResultSetMetaData rsmd) throws SQLException; + + public abstract void writeRow(PrintWriter out, ResultSet resultSet, int colCount) throws SQLException; + + public abstract void writeEndResultSet(PrintWriter out); + + public abstract void writeUpdate(PrintWriter out, int updateCount); + + public abstract void writeBeginResultSet(PrintWriter out); + + public abstract String getMime(); + + public static String repeatChar(char c, int length) { + return new String(new char[length]).replace('\0', c); + } + +} \ No newline at end of file diff --git a/src/main/java/es/jdlopez/sqlcmd/RunnerConfig.java b/src/main/java/es/jdlopez/sqlcmd/RunnerConfig.java index 72d8831..d28171d 100644 --- a/src/main/java/es/jdlopez/sqlcmd/RunnerConfig.java +++ b/src/main/java/es/jdlopez/sqlcmd/RunnerConfig.java @@ -20,6 +20,21 @@ public class RunnerConfig { private String mailPass; private String mailFrom; private String mailSubject; + private String formatterName; + + private ResultFormatter formatter = null; + public ResultFormatter buildFormatter() { + if (formatter == null) { + if (ResultFormatter.HTML.equalsIgnoreCase(formatterName)) + formatter = new HtmlFormatter(this); + else if (ResultFormatter.CSV.equalsIgnoreCase(formatterName)) + formatter = new CsvFormatter(this); + //if (ResultFormatter.TEXT.equalsIgnoreCase(formatterName)) + else + formatter = new TextFormatter(this); + } + return formatter; + } public String getInputSQL() { return inputSQL; @@ -164,4 +179,12 @@ public String getMailSubject() { public void setMailSubject(String mailSubject) { this.mailSubject = mailSubject; } + + public String getFormatterName() { + return formatterName; + } + + public void setFormatterName(String formatterName) { + this.formatterName = formatterName; + } } diff --git a/src/main/java/es/jdlopez/sqlcmd/SendMail.java b/src/main/java/es/jdlopez/sqlcmd/SendMail.java index 3afb26f..d055f9a 100644 --- a/src/main/java/es/jdlopez/sqlcmd/SendMail.java +++ b/src/main/java/es/jdlopez/sqlcmd/SendMail.java @@ -56,4 +56,14 @@ public void sendText(String subject, String body, String to) throws MessagingExc Transport.send(msg); } + + public void sendMime(String mime, String subject, String body, String to) throws MessagingException { + Session session = Session.getInstance(sessionProps, auth); + Message msg = new MimeMessage(session); + msg.setFrom(new InternetAddress(from)); + msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false)); + msg.setSubject(subject); + msg.setContent(body, mime); + Transport.send(msg); + } } diff --git a/src/main/java/es/jdlopez/sqlcmd/TextFormatter.java b/src/main/java/es/jdlopez/sqlcmd/TextFormatter.java new file mode 100644 index 0000000..cf429a1 --- /dev/null +++ b/src/main/java/es/jdlopez/sqlcmd/TextFormatter.java @@ -0,0 +1,68 @@ +package es.jdlopez.sqlcmd; + +import java.io.PrintWriter; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +public class TextFormatter extends ResultFormatter { + private RunnerConfig conf; + + public TextFormatter(RunnerConfig c) { + this.conf = c; + } + + @Override + public void writeHeader(PrintWriter out, ResultSetMetaData rsmd) throws SQLException { + int colCount = rsmd.getColumnCount(); + if (conf.getPrintHeader()) { + StringBuffer underline = new StringBuffer(); + for (int i = 1; i <= colCount; i++) { + out.print(rsmd.getColumnName(i)); + underline.append(repeatChar('=', rsmd.getColumnName(i).length())); + if (i < colCount) { + out.print(conf.getPrintFieldSeparator()); + underline.append(conf.getPrintFieldSeparator()); + } + } + out.println(); + out.println(underline.toString()); + } // header + + } + + @Override + public void writeRow(PrintWriter out, ResultSet resultSet, int colCount) throws SQLException { + for (int i = 1; i <= colCount; i++) { + out.print(resultSet.getString(i)); + if (i < colCount) + out.print(conf.getPrintFieldSeparator()); + } // for col + out.println(); + } + + @Override + public void writeEndResultSet(PrintWriter out) { + // nothing needed + } + + @Override + public void writeBeginResultSet(PrintWriter out) { + // nothing needed + } + + @Override + public void writeUpdate(PrintWriter out, int updateCount) { + String s; + if (conf.getPrintHeader()) + s = String.format("==================\nUpdateCount = %d\n==================", updateCount); + else + s = "UpdateCount = " + updateCount; + out.println(s); + } + + @Override + public String getMime() { + return "text/plain"; + } +} diff --git a/src/test/resources/sample.properties b/src/test/resources/sample.properties index 6531d81..5032405 100644 --- a/src/test/resources/sample.properties +++ b/src/test/resources/sample.properties @@ -6,8 +6,11 @@ jdbcUser=SA jdbcPass= # mail config -mailFrom=noreply@example.com -mailSubject=SqlCmd subject sent mailSendTo=nobody@example.com +mailSubject=SqlCmd subject sent +# mail server +mailFrom=noreply@example.com mailHost=localhost mailPort=25 + +formatterName=html \ No newline at end of file