Skip to content

Instantly share code, notes, and snippets.

@uklance
Created August 22, 2017 13:35
Show Gist options
  • Save uklance/c250409300f16664654d750b66e819cb to your computer and use it in GitHub Desktop.
Save uklance/c250409300f16664654d750b66e819cb to your computer and use it in GitHub Desktop.
Gradle SQL execution without polluting buildscript classloader
import java.sql.*;
import org.gradle.api.*;
import org.gradle.api.artifacts.*;
import org.gradle.api.tasks.*;
import java.util.*;
import java.net.*;
import java.io.File;
import java.lang.reflect.Method;
public abstract class AbstractSqlTask extends DefaultTask { 
private Action<Connection> connectionAction; 
private String url; 
private String driverClass; 
private Properties properties = new Properties();
private List<Dependency> dependencies;  
protected void setConnectionAction(Action<Connection> connectionAction) {  
this.connectionAction = connectionAction; 
}  
public void setUrl(String url) { 
this.url = url; 
}  
public void setDriverClass(String driverClass) {  
this.driverClass = driverClass; 
}  
public void setUser(String user) {  
properties.setProperty("user", user); 
}  
public void setPassword(String password) {  
properties.setProperty("password", password); 
}  
public void executeAction() throws Exception {  
assertParameter("driverClass", driverClass);  
assertParameter("url", url);  
assertParameter("dependencies", dependencies);    
try (Connection con = getConnection()) {  
connectionAction.execute(con);  
}  
public void dependency(Object dependency) {  
if (dependencies == null) {   
dependencies = new ArrayList<Dependency>();  
}  
dependencies.add(getProject().getDependencies().create(dependency)); 
}  
protected void assertParameter(String name, Object value) {  
if (value == null) {   
throw new RuntimeException(name + " not provided for " + getName()); 
}  
protected Connection getConnection() throws Exception {  
Configuration config = getProject().getConfigurations().create("sqlTask" + UUID.randomUUID().toString());  
for (Dependency dependency : dependencies) {   
config.getDependencies().add(dependency);  
}  
Set<File> files = config.getFiles();  
URL[] urls = new URL[files.size()];  
int i = 0;  for (Iterator<File> it = files.iterator(); it.hasNext(); ++i) {   
urls[i] = it.next().toURI().toURL();  
}  
URLClassLoader classloader = new URLClassLoader(urls, null); // no parent  
Driver driver = (Driver) classloader.loadClass(driverClass).newInstance();    
return driver.connect(url, properties); 
}
}
repositories {
...
}
task doQuery(type: SqlQueryTask) { 
dependency 'ojdbc6:ojdbc6:11.2.0.3' 
sql = "select 'foo' from dual" 
url = 'jdbc:oracle:thin:@foo:1234' 
user = 'user' 
password = 'password' 
driverClass = 'oracle.jdbc.driver.OracleDriver' 
action = { java.sql.ResultSet rs ->  
rs.next()  
println "Result: ${rs.getString(1)}" 
}
}
import java.sql.*;
import org.gradle.api.*;
import org.gradle.api.artifacts.*;
import org.gradle.api.tasks.*;
import java.util.*;
import java.net.*;
import java.io.File;
import java.lang.reflect.Method;
public class SqlQueryTask extends AbstractSqlTask { 
private String sql; 
private List<Object> parameters = new ArrayList<Object>(); 
private Action<ResultSet> action;  
public SqlQueryTask() {  
Action<Connection> connectionAction = new Action<Connection>() {   
public void execute(Connection connection) {    
try {     
if (parameters.isEmpty()) {      
try (Statement statement = connection.createStatement()) {       
ResultSet rs = statement.executeQuery(sql);       
action.execute(rs);       
rs.close();      
}     
} else {      
try (PreparedStatement statement = connection.prepareStatement(sql)) {       
int i = 1;       
for (Iterator<Object> it = parameters.iterator(); it.hasNext(); ++i) {        
statement.setObject(i, it.next());       
}       
ResultSet rs = statement.executeQuery(sql);       
action.execute(rs);       
rs.close();      
}    
}    
} catch (Exception e) {    
throw new RuntimeException(e);    
}   
}  
};  
setConnectionAction(connectionAction); 
}  
@TaskAction 
public void executeAction() throws Exception {  
assertParameter("sql", sql);  
assertParameter("action", action);  
super.executeAction(); 
}  
public void setSql(String sql) { 
this.sql = sql; 
}  
public void parameter(Object param) {  
parameters.add(param); 
}  
public void setAction(Action<ResultSet> action) {  
this.action = action; 
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment