Skip to content

Commit

Permalink
Added results sendmail on success. Some header decorations. Better ha…
Browse files Browse the repository at this point in the history
…ndling of multiple-results
  • Loading branch information
jdlopez committed Mar 15, 2022
1 parent 2a1af3d commit b1786c4
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 16 deletions.
27 changes: 23 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# sqlcmd
SQL command line executor using JDBC drivers. Useful for cron jobs and some automation. Porting of my previous sf.net code
SQL command line executor using JDBC drivers. Useful for cron jobs and some automation.

_Porting of my previous sf.net code_

Usage:

Expand All @@ -8,10 +10,10 @@ Usage:
FROM MY_TABLE
EOF

Config values:
## Config values:

* jdbcDriverPath=Path to jdbc driver jar (loaded dynamically)
* jdbcDriverClass=Jdbc Driver class full name
* jdbcDriverPath=Path to jdbc driver jar (loaded dynamically) if null it must be in classpath
* jdbcDriverClass=Jdbc Driver class full name (no need if driver registers itself)
* jdbcUrl=Jdbc connection URL
* jdbcUser=
* jdbcPass=
Expand All @@ -20,6 +22,23 @@ Config values:
* printHeader=true/false If true adds header with query's column name. Default true
* printFieldSeparator=Field separator for printing. Default tab (\t)

## Mail config values:

Mail Server:
* mailHost=SMTP host
* mailPort=SMTP port
* mailAuth=true/false smtp server needs authentication?
* mailTLS=true/false smtp server needs TLS connection?
* mailUser=smtp auth username
* mailPass=smtp auth password
*
Mail message:
* mailFrom=Email addess in from field
* mailSubject=Subject field
* mailSendTo=Email addess in TO field

## Config notes

Config values can be set also with parameters:

-p:paran_name=param_value
Expand Down
19 changes: 18 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,32 @@

<groupId>io.github.jdlopez</groupId>
<artifactId>sqlcmd</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.1</version>

<dependencies>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.4.1.jre8</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
67 changes: 60 additions & 7 deletions src/main/java/es/jdlopez/sqlcmd/MainRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import java.io.InputStream;
import java.io.InputStreamReader;
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;
import java.sql.SQLException;
Expand All @@ -30,24 +33,55 @@ public static void main (String[] args) throws Exception {
}
String sql = readAll(in);
PrintWriter out = null;
if (config.getOutputResult() == null)
out = new PrintWriter(System.out);
StringWriter mailBody = null;
if (config.getMailSendTo() != null) {
mailBody = new StringWriter();
out = new PrintWriter(mailBody);
}
else if (config.getOutputResult() == null)
out = new PrintWriter(System.out, true);
else
out = new PrintWriter(config.getOutputResult());

Connection conn = null;
try {
conn = DynamicDriver.getConnection(config.getJdbcDriverPath(), config.getJdbcDriverClass(),
if (config.getJdbcDriverPath() == null) {
// driver in classpath and registered
conn = DriverManager.getConnection(config.getJdbcUrl(), config.getJdbcUser(), config.getJdbcPass());
} else
conn = DynamicDriver.getConnection(config.getJdbcDriverPath(), config.getJdbcDriverClass(),
config.getJdbcUrl(), config.getJdbcUser(), config.getJdbcPass());
Statement st = conn.createStatement();
boolean isResultSet = st.execute(sql);
boolean hasMore = true;
int updateCount = st.getUpdateCount(); // just once per result
while (hasMore) {
if (isResultSet)
if (isResultSet && updateCount < 0)
writeResultSet(st.getResultSet(), out, config);
else
out.println("UpdateCount = " + st.getUpdateCount());
hasMore = st.getMoreResults();
writeUpdateCount(updateCount, out, config);
isResultSet = st.getMoreResults();
updateCount = st.getUpdateCount();
hasMore = isResultSet || updateCount > -1;
}
// send result to mail?
if (config.getMailSendTo() != null && mailBody != null) {
SendMail sendMail;
if (config.getMailAuth() != null) {
sendMail = new SendMail(config.getMailHost(),
config.getMailPort(),
config.getMailFrom(),
Boolean.valueOf(config.getMailAuth()),
Boolean.valueOf(config.getMailTLS()),
config.getMailUser(),
config.getMailPass()
);
} else {
sendMail = new SendMail(config.getMailHost(),
config.getMailPort(),
config.getMailFrom());
}
sendMail.sendText(config.getMailSubject(), mailBody.toString(), config.getMailSendTo());
}

} finally {
Expand All @@ -56,16 +90,31 @@ public static void main (String[] args) throws Exception {
}
}

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);

}

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));
if (i < colCount)
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
while (resultSet.next()) {
for (int i = 1; i <= colCount; i++) {
Expand All @@ -78,6 +127,10 @@ private static void writeResultSet(ResultSet resultSet, PrintWriter out, RunnerC
out.flush();
}

private static String repeatChar(char c, int length) {
return new String(new char[length]).replace('\0', c);
}

private static String readAll(InputStream in) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuffer sb = new StringBuffer();
Expand Down
82 changes: 82 additions & 0 deletions src/main/java/es/jdlopez/sqlcmd/RunnerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ public class RunnerConfig {
private String outputResult;
private Boolean printHeader = true;
private String printFieldSeparator = "\t";
// mail configuration:
private String mailSendTo;
private String mailHost;
private String mailPort;
private Boolean mailAuth;
private Boolean mailTLS;
private String mailUser;
private String mailPass;
private String mailFrom;
private String mailSubject;

public String getInputSQL() {
return inputSQL;
Expand Down Expand Up @@ -82,4 +92,76 @@ public String getPrintFieldSeparator() {
public void setPrintFieldSeparator(String printFieldSeparator) {
this.printFieldSeparator = printFieldSeparator;
}

public String getMailSendTo() {
return mailSendTo;
}

public void setMailSendTo(String mailSendTo) {
this.mailSendTo = mailSendTo;
}

public String getMailHost() {
return mailHost;
}

public void setMailHost(String mailHost) {
this.mailHost = mailHost;
}

public String getMailPort() {
return mailPort;
}

public void setMailPort(String mailPort) {
this.mailPort = mailPort;
}

public Boolean getMailAuth() {
return mailAuth;
}

public void setMailAuth(Boolean mailAuth) {
this.mailAuth = mailAuth;
}

public Boolean getMailTLS() {
return mailTLS;
}

public void setMailTLS(Boolean mailTLS) {
this.mailTLS = mailTLS;
}

public String getMailUser() {
return mailUser;
}

public void setMailUser(String mailUser) {
this.mailUser = mailUser;
}

public String getMailPass() {
return mailPass;
}

public void setMailPass(String mailPass) {
this.mailPass = mailPass;
}

public String getMailFrom() {
return mailFrom;
}

public void setMailFrom(String mailFrom) {
this.mailFrom = mailFrom;
}

public String getMailSubject() {
return mailSubject;
}

public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
}
59 changes: 59 additions & 0 deletions src/main/java/es/jdlopez/sqlcmd/SendMail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package es.jdlopez.sqlcmd;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class SendMail {

private Authenticator auth;
private Properties sessionProps;
private String from;

public SendMail(String host, String port, String from) {
this(host, port, from, false, false, null, null);
}
public SendMail(String host, String port, String from, boolean auth, boolean tls, String user, String pass) {
this.from = from;
this.sessionProps = new Properties();
sessionProps.setProperty("mail.smtp.host", host);
sessionProps.setProperty("mail.smtp.port", port);
if (auth) {
sessionProps.setProperty("mail.smtp.auth", "true");
// just user pass authenticator
this.auth = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pass);
}
};
}
if (tls)
sessionProps.setProperty("mail.smtp.starttls.enable", "true");

}

public void sendText(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.setText(body);
// Let's tranport sets default value
//msg.setHeader("X-Mailer", mailer);
//msg.setSentDate(new Date());

Transport.send(msg);
}
}
24 changes: 24 additions & 0 deletions src/test/java/es/jdlopez/sqlcmd/TestMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package es.jdlopez.sqlcmd;

import org.junit.Test;

import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class TestMain {

@Test
public void testCreateTable() throws Exception {
// create table must be in previous statement: hsqldb docs
Properties p = new Properties();
p.load(new FileReader("src/test/resources/sample.properties"));
Connection conn = DriverManager.getConnection(p.getProperty("jdbcUrl"),
p.getProperty("jdbcUser"), p.getProperty("jdbcPass"));
conn.createStatement().executeUpdate("create table testtable1 ( field1 int, field2 varchar(10))");
String[] args = new String[]{"-c:src/test/resources/sample.properties", "-p:inputSQL=src/test/resources/test1.sql"};
MainRunner.main(args);
conn.createStatement().executeUpdate("drop table testtable1");
}
}
15 changes: 11 additions & 4 deletions src/test/resources/sample.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# database connection properties
jdbcDriverPath=
jdbcDriverClass=
jdbcUrl=
jdbcUser=
#jdbcDriverPath=
#jdbcDriverClass=
jdbcUrl=jdbc:hsqldb:mem:mymemdb
jdbcUser=SA
jdbcPass=

# mail config
mailFrom=[email protected]
mailSubject=SqlCmd subject sent
mailSendTo=[email protected]
mailHost=localhost
mailPort=25
Loading

0 comments on commit b1786c4

Please sign in to comment.