001    
002    /*
003     * Copyright (C) 2011 Archie L. Cobbs. All rights reserved.
004     *
005     * $Id: SQLCommand.java 205 2012-01-06 22:43:05Z archie.cobbs $
006     */
007    
008    package org.dellroad.stuff.schema;
009    
010    import java.sql.Connection;
011    import java.sql.SQLException;
012    import java.sql.Statement;
013    
014    import org.slf4j.Logger;
015    import org.slf4j.LoggerFactory;
016    
017    /**
018     * An SQL {@link DatabaseAction} that executes a single SQL statement.
019     */
020    public class SQLCommand implements DatabaseAction<Connection> {
021    
022        protected final Logger log = LoggerFactory.getLogger(this.getClass());
023    
024        private final String sql;
025    
026        /**
027         * Constructor.
028         *
029         * @param sql the SQL to execute; must be a single statement
030         * @throws IllegalArgumentException if {@code sql} is null or contains only whitespace
031         */
032        public SQLCommand(String sql) {
033            if (sql == null)
034                throw new IllegalArgumentException("null sql");
035            sql = sql.trim();
036            if (sql.length() == 0)
037                throw new IllegalArgumentException("empty sql");
038            this.sql = sql;
039        }
040    
041        public String getSQL() {
042            return this.sql;
043        }
044    
045        /**
046         * Execute the SQL statement.
047         *
048         * <p>
049         * The implementation in {@link SQLCommand} creates a {@link Statement} and then executes the configured
050         * SQL command via {@link Statement#execute}. Subclasses may wish to override.
051         *
052         * @throws SQLException if an error occurs while accessing the database
053         */
054        @Override
055        public void apply(Connection c) throws SQLException {
056            Statement statement = c.createStatement();
057            String sep = this.sql.indexOf('\n') != -1 ? "\n" : " ";
058            this.log.info("executing SQL statement:" + sep + this.sql);
059            try {
060                statement.execute(this.sql);
061            } finally {
062                statement.close();
063            }
064        }
065    }
066