Skip to content

Commit b1786c4

Browse files
committed
Added results sendmail on success. Some header decorations. Better handling of multiple-results
1 parent 2a1af3d commit b1786c4

File tree

8 files changed

+292
-16
lines changed

8 files changed

+292
-16
lines changed

README.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# sqlcmd
2-
SQL command line executor using JDBC drivers. Useful for cron jobs and some automation. Porting of my previous sf.net code
2+
SQL command line executor using JDBC drivers. Useful for cron jobs and some automation.
3+
4+
_Porting of my previous sf.net code_
35

46
Usage:
57

@@ -8,10 +10,10 @@ Usage:
810
FROM MY_TABLE
911
EOF
1012

11-
Config values:
13+
## Config values:
1214

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

25+
## Mail config values:
26+
27+
Mail Server:
28+
* mailHost=SMTP host
29+
* mailPort=SMTP port
30+
* mailAuth=true/false smtp server needs authentication?
31+
* mailTLS=true/false smtp server needs TLS connection?
32+
* mailUser=smtp auth username
33+
* mailPass=smtp auth password
34+
*
35+
Mail message:
36+
* mailFrom=Email addess in from field
37+
* mailSubject=Subject field
38+
* mailSendTo=Email addess in TO field
39+
40+
## Config notes
41+
2342
Config values can be set also with parameters:
2443

2544
-p:paran_name=param_value

pom.xml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,32 @@
66

77
<groupId>io.github.jdlopez</groupId>
88
<artifactId>sqlcmd</artifactId>
9-
<version>1.0-SNAPSHOT</version>
9+
<version>1.1</version>
1010

1111
<dependencies>
12+
<dependency>
13+
<groupId>com.sun.mail</groupId>
14+
<artifactId>javax.mail</artifactId>
15+
<version>1.6.2</version>
16+
</dependency>
1217
<dependency>
1318
<groupId>junit</groupId>
1419
<artifactId>junit</artifactId>
1520
<version>4.12</version>
1621
<scope>test</scope>
1722
</dependency>
23+
<dependency>
24+
<groupId>org.hsqldb</groupId>
25+
<artifactId>hsqldb</artifactId>
26+
<version>2.3.2</version>
27+
<scope>test</scope>
28+
</dependency>
29+
<dependency>
30+
<groupId>com.microsoft.sqlserver</groupId>
31+
<artifactId>mssql-jdbc</artifactId>
32+
<version>7.4.1.jre8</version>
33+
<scope>test</scope>
34+
</dependency>
1835
</dependencies>
1936

2037
<build>

src/main/java/es/jdlopez/sqlcmd/MainRunner.java

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
import java.io.InputStream;
99
import java.io.InputStreamReader;
1010
import java.io.PrintWriter;
11+
import java.io.StringWriter;
1112
import java.sql.Connection;
13+
import java.sql.Driver;
14+
import java.sql.DriverManager;
1215
import java.sql.ResultSet;
1316
import java.sql.ResultSetMetaData;
1417
import java.sql.SQLException;
@@ -30,24 +33,55 @@ public static void main (String[] args) throws Exception {
3033
}
3134
String sql = readAll(in);
3235
PrintWriter out = null;
33-
if (config.getOutputResult() == null)
34-
out = new PrintWriter(System.out);
36+
StringWriter mailBody = null;
37+
if (config.getMailSendTo() != null) {
38+
mailBody = new StringWriter();
39+
out = new PrintWriter(mailBody);
40+
}
41+
else if (config.getOutputResult() == null)
42+
out = new PrintWriter(System.out, true);
3543
else
3644
out = new PrintWriter(config.getOutputResult());
3745

3846
Connection conn = null;
3947
try {
40-
conn = DynamicDriver.getConnection(config.getJdbcDriverPath(), config.getJdbcDriverClass(),
48+
if (config.getJdbcDriverPath() == null) {
49+
// driver in classpath and registered
50+
conn = DriverManager.getConnection(config.getJdbcUrl(), config.getJdbcUser(), config.getJdbcPass());
51+
} else
52+
conn = DynamicDriver.getConnection(config.getJdbcDriverPath(), config.getJdbcDriverClass(),
4153
config.getJdbcUrl(), config.getJdbcUser(), config.getJdbcPass());
4254
Statement st = conn.createStatement();
4355
boolean isResultSet = st.execute(sql);
4456
boolean hasMore = true;
57+
int updateCount = st.getUpdateCount(); // just once per result
4558
while (hasMore) {
46-
if (isResultSet)
59+
if (isResultSet && updateCount < 0)
4760
writeResultSet(st.getResultSet(), out, config);
4861
else
49-
out.println("UpdateCount = " + st.getUpdateCount());
50-
hasMore = st.getMoreResults();
62+
writeUpdateCount(updateCount, out, config);
63+
isResultSet = st.getMoreResults();
64+
updateCount = st.getUpdateCount();
65+
hasMore = isResultSet || updateCount > -1;
66+
}
67+
// send result to mail?
68+
if (config.getMailSendTo() != null && mailBody != null) {
69+
SendMail sendMail;
70+
if (config.getMailAuth() != null) {
71+
sendMail = new SendMail(config.getMailHost(),
72+
config.getMailPort(),
73+
config.getMailFrom(),
74+
Boolean.valueOf(config.getMailAuth()),
75+
Boolean.valueOf(config.getMailTLS()),
76+
config.getMailUser(),
77+
config.getMailPass()
78+
);
79+
} else {
80+
sendMail = new SendMail(config.getMailHost(),
81+
config.getMailPort(),
82+
config.getMailFrom());
83+
}
84+
sendMail.sendText(config.getMailSubject(), mailBody.toString(), config.getMailSendTo());
5185
}
5286

5387
} finally {
@@ -56,16 +90,31 @@ public static void main (String[] args) throws Exception {
5690
}
5791
}
5892

93+
private static void writeUpdateCount(int updateCount, PrintWriter out, RunnerConfig config) {
94+
String s;
95+
if (config.getPrintHeader())
96+
s = String.format("==================\nUpdateCount = %d\n==================", updateCount);
97+
else
98+
s = "UpdateCount = " + updateCount;
99+
out.println(s);
100+
101+
}
102+
59103
private static void writeResultSet(ResultSet resultSet, PrintWriter out, RunnerConfig conf) throws SQLException {
60104
ResultSetMetaData rsmd = resultSet.getMetaData();
61105
int colCount = rsmd.getColumnCount();
62106
if (conf.getPrintHeader()) {
107+
StringBuffer underline = new StringBuffer();
63108
for (int i = 1; i <= colCount; i++) {
64109
out.print(rsmd.getColumnName(i));
65-
if (i < colCount)
110+
underline.append(repeatChar('=', rsmd.getColumnName(i).length()));
111+
if (i < colCount) {
66112
out.print(conf.getPrintFieldSeparator());
113+
underline.append(conf.getPrintFieldSeparator());
114+
}
67115
}
68116
out.println();
117+
out.println(underline.toString());
69118
} // header
70119
while (resultSet.next()) {
71120
for (int i = 1; i <= colCount; i++) {
@@ -78,6 +127,10 @@ private static void writeResultSet(ResultSet resultSet, PrintWriter out, RunnerC
78127
out.flush();
79128
}
80129

130+
private static String repeatChar(char c, int length) {
131+
return new String(new char[length]).replace('\0', c);
132+
}
133+
81134
private static String readAll(InputStream in) throws IOException {
82135
BufferedReader br = new BufferedReader(new InputStreamReader(in));
83136
StringBuffer sb = new StringBuffer();

src/main/java/es/jdlopez/sqlcmd/RunnerConfig.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ public class RunnerConfig {
1010
private String outputResult;
1111
private Boolean printHeader = true;
1212
private String printFieldSeparator = "\t";
13+
// mail configuration:
14+
private String mailSendTo;
15+
private String mailHost;
16+
private String mailPort;
17+
private Boolean mailAuth;
18+
private Boolean mailTLS;
19+
private String mailUser;
20+
private String mailPass;
21+
private String mailFrom;
22+
private String mailSubject;
1323

1424
public String getInputSQL() {
1525
return inputSQL;
@@ -82,4 +92,76 @@ public String getPrintFieldSeparator() {
8292
public void setPrintFieldSeparator(String printFieldSeparator) {
8393
this.printFieldSeparator = printFieldSeparator;
8494
}
95+
96+
public String getMailSendTo() {
97+
return mailSendTo;
98+
}
99+
100+
public void setMailSendTo(String mailSendTo) {
101+
this.mailSendTo = mailSendTo;
102+
}
103+
104+
public String getMailHost() {
105+
return mailHost;
106+
}
107+
108+
public void setMailHost(String mailHost) {
109+
this.mailHost = mailHost;
110+
}
111+
112+
public String getMailPort() {
113+
return mailPort;
114+
}
115+
116+
public void setMailPort(String mailPort) {
117+
this.mailPort = mailPort;
118+
}
119+
120+
public Boolean getMailAuth() {
121+
return mailAuth;
122+
}
123+
124+
public void setMailAuth(Boolean mailAuth) {
125+
this.mailAuth = mailAuth;
126+
}
127+
128+
public Boolean getMailTLS() {
129+
return mailTLS;
130+
}
131+
132+
public void setMailTLS(Boolean mailTLS) {
133+
this.mailTLS = mailTLS;
134+
}
135+
136+
public String getMailUser() {
137+
return mailUser;
138+
}
139+
140+
public void setMailUser(String mailUser) {
141+
this.mailUser = mailUser;
142+
}
143+
144+
public String getMailPass() {
145+
return mailPass;
146+
}
147+
148+
public void setMailPass(String mailPass) {
149+
this.mailPass = mailPass;
150+
}
151+
152+
public String getMailFrom() {
153+
return mailFrom;
154+
}
155+
156+
public void setMailFrom(String mailFrom) {
157+
this.mailFrom = mailFrom;
158+
}
159+
160+
public String getMailSubject() {
161+
return mailSubject;
162+
}
163+
164+
public void setMailSubject(String mailSubject) {
165+
this.mailSubject = mailSubject;
166+
}
85167
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package es.jdlopez.sqlcmd;
2+
3+
import javax.mail.Authenticator;
4+
import javax.mail.Message;
5+
import javax.mail.MessagingException;
6+
import javax.mail.PasswordAuthentication;
7+
import javax.mail.Session;
8+
import javax.mail.Transport;
9+
import javax.mail.internet.InternetAddress;
10+
import javax.mail.internet.MimeMessage;
11+
import java.util.Properties;
12+
13+
public class SendMail {
14+
15+
private Authenticator auth;
16+
private Properties sessionProps;
17+
private String from;
18+
19+
public SendMail(String host, String port, String from) {
20+
this(host, port, from, false, false, null, null);
21+
}
22+
public SendMail(String host, String port, String from, boolean auth, boolean tls, String user, String pass) {
23+
this.from = from;
24+
this.sessionProps = new Properties();
25+
sessionProps.setProperty("mail.smtp.host", host);
26+
sessionProps.setProperty("mail.smtp.port", port);
27+
if (auth) {
28+
sessionProps.setProperty("mail.smtp.auth", "true");
29+
// just user pass authenticator
30+
this.auth = new Authenticator() {
31+
@Override
32+
protected PasswordAuthentication getPasswordAuthentication() {
33+
return new PasswordAuthentication(user, pass);
34+
}
35+
};
36+
}
37+
if (tls)
38+
sessionProps.setProperty("mail.smtp.starttls.enable", "true");
39+
40+
}
41+
42+
public void sendText(String subject, String body, String to) throws MessagingException {
43+
Session session = Session.getInstance(sessionProps, auth);
44+
Message msg = new MimeMessage(session);
45+
46+
msg.setFrom(new InternetAddress(from));
47+
48+
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
49+
50+
msg.setSubject(subject);
51+
52+
msg.setText(body);
53+
// Let's tranport sets default value
54+
//msg.setHeader("X-Mailer", mailer);
55+
//msg.setSentDate(new Date());
56+
57+
Transport.send(msg);
58+
}
59+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package es.jdlopez.sqlcmd;
2+
3+
import org.junit.Test;
4+
5+
import java.io.FileReader;
6+
import java.sql.Connection;
7+
import java.sql.DriverManager;
8+
import java.util.Properties;
9+
10+
public class TestMain {
11+
12+
@Test
13+
public void testCreateTable() throws Exception {
14+
// create table must be in previous statement: hsqldb docs
15+
Properties p = new Properties();
16+
p.load(new FileReader("src/test/resources/sample.properties"));
17+
Connection conn = DriverManager.getConnection(p.getProperty("jdbcUrl"),
18+
p.getProperty("jdbcUser"), p.getProperty("jdbcPass"));
19+
conn.createStatement().executeUpdate("create table testtable1 ( field1 int, field2 varchar(10))");
20+
String[] args = new String[]{"-c:src/test/resources/sample.properties", "-p:inputSQL=src/test/resources/test1.sql"};
21+
MainRunner.main(args);
22+
conn.createStatement().executeUpdate("drop table testtable1");
23+
}
24+
}
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# database connection properties
2-
jdbcDriverPath=
3-
jdbcDriverClass=
4-
jdbcUrl=
5-
jdbcUser=
2+
#jdbcDriverPath=
3+
#jdbcDriverClass=
4+
jdbcUrl=jdbc:hsqldb:mem:mymemdb
5+
jdbcUser=SA
66
jdbcPass=
7+
8+
# mail config
9+
mailFrom=noreply@example.com
10+
mailSubject=SqlCmd subject sent
11+
mailSendTo=nobody@example.com
12+
mailHost=localhost
13+
mailPort=25

0 commit comments

Comments
 (0)