Java tutorial
/** * e3db Fast database library for Grails * Copyright (C) 2009-2010 Collegeman.net, LLC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package net.collegeman.grails.e3db; import java.util.*; import java.sql.*; import javax.sql.*; import groovy.lang.*; import java.util.regex.*; import org.apache.log4j.*; import org.springframework.context.ApplicationContext; import org.springframework.util.StringUtils; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.jdbc.core.simple.*; import org.springframework.jdbc.datasource.*; import org.springframework.transaction.*; import org.springframework.transaction.support.*; public class Template extends SqlBuffer { protected static final Logger log = Logger.getLogger("net.collegeman.grails.e3db"); private static final Pattern multiLineWhitespace = Pattern.compile("[\\n\\r\\t]"); private static final Pattern extraSpaces = Pattern.compile(" +"); private static final String removeWhitespace(String string) { string = multiLineWhitespace.matcher(string).replaceAll(" "); return extraSpaces.matcher(string).replaceAll(" "); } protected static final String METHOD_ROW_SET = "rowSet"; protected static final String METHOD_LIST = "list"; protected static final String METHOD_OBJECT = "object"; protected DataSource dataSource; protected SimpleJdbcTemplate simpleJdbcTemplate; protected TransactionTemplate transactionTemplate; // an instance of Query is defined in plugin hook doWithSpring to grab app context and default data source protected static ApplicationContext ctx; protected static DataSource defaultDataSource; protected static SimpleJdbcTemplate defaultSimpleJdbcTemplate; protected static TransactionTemplate defaultTransactionTemplate; protected static final void setApplicationContext(ApplicationContext applicationContext) { ctx = applicationContext; // first, go for grails default "dataSource" try { defaultDataSource = (DataSource) ctx.getBean("dataSource"); defaultSimpleJdbcTemplate = new SimpleJdbcTemplate(defaultDataSource); } catch (NoSuchBeanDefinitionException e) { log.warn( "No default DataSource bean named [dataSource] found in application context - a DataSource will need to be created manually for E3DB."); } // then, try to setup the transaction template if (defaultDataSource != null) { try { defaultTransactionTemplate = new TransactionTemplate( (PlatformTransactionManager) ctx.getBean("transactionManager")); } catch (NoSuchBeanDefinitionException e) { defaultTransactionTemplate = new TransactionTemplate( new DataSourceTransactionManager(defaultDataSource)); log.info("DataSourceTranactionManager created by and for E3DB."); } } } public static void setDefaultDataSource(DataSource dataSource) { defaultDataSource = dataSource; defaultSimpleJdbcTemplate = new SimpleJdbcTemplate(defaultDataSource); defaultTransactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(defaultDataSource)); } public final TransactionTemplate getTransactionTemplate() { if (transactionTemplate != null) return transactionTemplate; else if (defaultTransactionTemplate != null) return defaultTransactionTemplate; else { log.warn("No Transaction Management available to E3DB."); return null; } } protected SimpleJdbcTemplate getSJT() { if (simpleJdbcTemplate != null) return simpleJdbcTemplate; else if (defaultSimpleJdbcTemplate != null) return defaultSimpleJdbcTemplate; else throw new IllegalStateException("DataSource for E3DB Template has not be initialized."); } protected final static <T> T query(String method, Closure closure, Class<T> requiredType) { Template t = new Template(); closure.setDelegate(t); closure.setResolveStrategy(Closure.DELEGATE_FIRST); Object sql = closure.call(); if (hasLength(sql)) t.sql(String.valueOf(sql)); return (T) query(method, t.getSql(), requiredType, t.getQueryParams()); } protected final static <T> T query(String method, String sql, Class<T> requiredType, Object... args) { if (shouldLogSql()) logSql(sql, args); if (args != null && args.length > 0) { if (args[0] instanceof Map) { Map map = (Map) args[0]; if (METHOD_LIST.equals(method)) { return (T) new Template().getSJT().queryForList(sql, map); } else if (METHOD_OBJECT.equals(method)) { return (T) new Template().getSJT().queryForObject(sql, requiredType, map); } else if (METHOD_ROW_SET.equals(method)) { throw new IllegalStateException( "rows() does not support named parameters. You must use listed parameters instead, e.g., rows('SELECT * FROM ...', param1, param2, ...) or rows { sql('SELECT * FROM ...', param1, param2, ...) }."); } else { throw new IllegalStateException("Unrecognized query method: " + method); } } else { if (args[0] instanceof List) { args = ((List) args[0]).toArray(); } if (METHOD_LIST.equals(method)) { return (T) new Template().getSJT().queryForList(sql, args); } else if (METHOD_OBJECT.equals(method)) { return (T) new Template().getSJT().queryForObject(sql, requiredType, args); } else if (METHOD_ROW_SET.equals(method)) { return (T) new Template().getSJT().getJdbcOperations().queryForRowSet(sql, args); } else { throw new IllegalStateException("Unrecognized query method: " + method); } } } else { if (METHOD_LIST.equals(method)) { return (T) new Template().getSJT().queryForList(sql); } else if (METHOD_OBJECT.equals(method)) { return (T) new Template().getSJT().queryForObject(sql, requiredType); } else if (METHOD_ROW_SET.equals(method)) { return (T) new Template().getSJT().getJdbcOperations().queryForRowSet(sql); } else { throw new IllegalStateException("Unrecognized query method: " + method); } } } public final static int exec(Closure closure) { Template t = new Template(); closure.setDelegate(t); closure.setResolveStrategy(Closure.DELEGATE_FIRST); Object sql = closure.call(); if (hasLength(sql)) t.sql(String.valueOf(sql)); return exec(t.getSql(), t.getQueryParams()); } public final static int exec(String sql, Object... args) { if (shouldLogSql()) logSql(sql, args); return new Template().getSJT().update(sql, args); } public final static void logSql(String sql, Object args) { String clearSql = removeWhitespace(sql); Object printableArgs; if (args != null && args.getClass().isArray()) printableArgs = Arrays.asList((Object[]) args); else printableArgs = args; if (log.isDebugEnabled()) log.debug(clearSql + ": " + printableArgs); if (System.getProperty("net.collegeman.grails.e3db.printSql") == "true") System.out.println("e3db.Template: " + clearSql + ": " + printableArgs); } public final static boolean shouldLogSql() { return (log.isDebugEnabled() || System.getProperty("net.collegeman.grails.e3db.printSql") == "true"); } /** * @param name The name of a dataSource bean in Application context. */ public final void dataSource(String name) { if (ctx == null) throw new IllegalStateException("ApplicationContext not initialized."); dataSource((DataSource) ctx.getBean(name)); } public final void dataSource(Map<String, Object> config) { Driver driverInstance = null; Object driver = config.get("driver"); try { if (driver == null) throw new IllegalArgumentException("driver configuration parameter cannot be null."); if (driver instanceof Class) { driverInstance = (Driver) ((Class) driver).newInstance(); } else if (driver instanceof String) { driverInstance = (Driver) Class.forName((String) driver).newInstance(); } else if (driver instanceof Driver) { driverInstance = (Driver) driver; } else { throw new IllegalArgumentException("driver is unrecognized type: " + driver.getClass()); } } catch (InstantiationException e) { throw new RuntimeException(e); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } dataSource(new SimpleDriverDataSource(driverInstance, String.valueOf(config.get("url")), String.valueOf(config.get("username")), String.valueOf(config.get("password")))); } /** * @param dataSource A JDBC DataSource implementation */ public final void dataSource(DataSource dataSource) { if (dataSource == null) throw new IllegalArgumentException("dataSource cannot be null."); this.dataSource = dataSource; simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource)); } public static final SqlBuffer buffer(Closure closure) { SqlBuffer buf = new SqlBuffer(); closure.setDelegate(buf); closure.setResolveStrategy(Closure.DELEGATE_FIRST); closure.call(); return buf; } }