001    /*
002     * The MIT License
003     *
004     * Copyright (c) 2012, Ninja Squad
005     *
006     * Permission is hereby granted, free of charge, to any person obtaining a copy
007     * of this software and associated documentation files (the "Software"), to deal
008     * in the Software without restriction, including without limitation the rights
009     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010     * copies of the Software, and to permit persons to whom the Software is
011     * furnished to do so, subject to the following conditions:
012     *
013     * The above copyright notice and this permission notice shall be included in
014     * all copies or substantial portions of the Software.
015     *
016     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
022     * THE SOFTWARE.
023     */
024    
025    package com.ninja_squad.dbsetup.operation;
026    
027    import java.sql.Connection;
028    import java.sql.SQLException;
029    import java.sql.Statement;
030    import java.util.ArrayList;
031    import java.util.Arrays;
032    import java.util.List;
033    
034    import javax.annotation.Nonnull;
035    import javax.annotation.concurrent.Immutable;
036    
037    import com.ninja_squad.dbsetup.bind.BinderConfiguration;
038    import com.ninja_squad.dbsetup.util.Preconditions;
039    
040    /**
041     * An operation which simply executes a SQL statement (using {@link Statement#executeUpdate(String)}). It can be useful,
042     * for example, to disable or re-enable constraints before/after deleting everything from tables, or inserting into
043     * tables having cross references.
044     * @author JB Nizet
045     */
046    @Immutable
047    public final class SqlOperation implements Operation {
048    
049        private final String sql;
050    
051        /**
052         * Constructor
053         * @param sql the SQL query to execute
054         */
055        private SqlOperation(String sql) {
056            Preconditions.checkNotNull(sql, "sql may not be null");
057            this.sql = sql;
058        }
059    
060        @Override
061        public void execute(Connection connection, BinderConfiguration configuration) throws SQLException {
062            Statement stmt = connection.createStatement();
063            try {
064                stmt.executeUpdate(sql);
065            }
066            finally {
067                stmt.close();
068            }
069        }
070    
071        /**
072         * Creates a SqlOperation for the given SQL statement
073         * @param sqlStatement the SQL statement to execute
074         * @return the created SqlOperation
075         */
076        public static SqlOperation of(@Nonnull String sqlStatement) {
077            return new SqlOperation(sqlStatement);
078        }
079    
080        /**
081         * Creates a sequence of SqlOperation for the given SQL statements.
082         * @param sqlStatements the SQL statements to execute
083         * @return the created sequence of operations
084         */
085        public static Operation of(@Nonnull String... sqlStatements) {
086            return of(Arrays.asList(sqlStatements));
087        }
088    
089        /**
090         * Creates a sequence of SqlOperation for the given SQL statements.
091         * @param sqlStatements the SQL statements to execute
092         * @return the created sequence of operations
093         */
094        public static Operation of(@Nonnull List<String> sqlStatements) {
095            List<SqlOperation> operations = new ArrayList<SqlOperation>(sqlStatements.size());
096            for (String sql : sqlStatements) {
097                operations.add(new SqlOperation(sql));
098            }
099            return CompositeOperation.sequenceOf(operations);
100        }
101    
102        @Override
103        public String toString() {
104            return sql;
105        }
106    
107        @Override
108        public int hashCode() {
109            return sql.hashCode();
110        }
111    
112        @Override
113        public boolean equals(Object o) {
114            if (o == this) {
115                return true;
116            }
117            if (o == null) {
118                return false;
119            }
120            if (o.getClass() != this.getClass()) {
121                return false;
122            }
123    
124            SqlOperation other = (SqlOperation) o;
125            return this.sql.equals(other.sql);
126        }
127    }