001/*
002 * Copyright 2002-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.test.context.jdbc;
018
019import java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Inherited;
022import java.lang.annotation.Repeatable;
023import java.lang.annotation.Retention;
024import java.lang.annotation.RetentionPolicy;
025import java.lang.annotation.Target;
026
027import org.springframework.core.annotation.AliasFor;
028
029/**
030 * {@code @Sql} is used to annotate a test class or test method to configure
031 * SQL {@link #scripts} and {@link #statements} to be executed against a given
032 * database during integration tests.
033 *
034 * <p>Method-level declarations override class-level declarations.
035 *
036 * <p>Script execution is performed by the {@link SqlScriptsTestExecutionListener},
037 * which is enabled by default.
038 *
039 * <p>The configuration options provided by this annotation and
040 * {@link SqlConfig @SqlConfig} are equivalent to those supported by
041 * {@link org.springframework.jdbc.datasource.init.ScriptUtils ScriptUtils} and
042 * {@link org.springframework.jdbc.datasource.init.ResourceDatabasePopulator ResourceDatabasePopulator}
043 * but are a superset of those provided by the {@code <jdbc:initialize-database/>}
044 * XML namespace element. Consult the javadocs of individual attributes in this
045 * annotation and {@link SqlConfig @SqlConfig} for details.
046 *
047 * <p>Beginning with Java 8, {@code @Sql} can be used as a
048 * <em>{@linkplain Repeatable repeatable}</em> annotation. Otherwise,
049 * {@link SqlGroup @SqlGroup} can be used as an explicit container for declaring
050 * multiple instances of {@code @Sql}.
051 *
052 * <p>This annotation may be used as a <em>meta-annotation</em> to create custom
053 * <em>composed annotations</em> with attribute overrides.
054 *
055 * @author Sam Brannen
056 * @since 4.1
057 * @see SqlConfig
058 * @see SqlGroup
059 * @see SqlScriptsTestExecutionListener
060 * @see org.springframework.transaction.annotation.Transactional
061 * @see org.springframework.test.context.transaction.TransactionalTestExecutionListener
062 * @see org.springframework.jdbc.datasource.init.ResourceDatabasePopulator
063 * @see org.springframework.jdbc.datasource.init.ScriptUtils
064 */
065@Target({ElementType.TYPE, ElementType.METHOD})
066@Retention(RetentionPolicy.RUNTIME)
067@Documented
068@Inherited
069@Repeatable(SqlGroup.class)
070public @interface Sql {
071
072        /**
073         * Alias for {@link #scripts}.
074         * <p>This attribute may <strong>not</strong> be used in conjunction with
075         * {@link #scripts}, but it may be used instead of {@link #scripts}.
076         * @see #scripts
077         * @see #statements
078         */
079        @AliasFor("scripts")
080        String[] value() default {};
081
082        /**
083         * The paths to the SQL scripts to execute.
084         * <p>This attribute may <strong>not</strong> be used in conjunction with
085         * {@link #value}, but it may be used instead of {@link #value}. Similarly,
086         * this attribute may be used in conjunction with or instead of
087         * {@link #statements}.
088         * <h3>Path Resource Semantics</h3>
089         * <p>Each path will be interpreted as a Spring
090         * {@link org.springframework.core.io.Resource Resource}. A plain path
091         * &mdash; for example, {@code "schema.sql"} &mdash; will be treated as a
092         * classpath resource that is <em>relative</em> to the package in which the
093         * test class is defined. A path starting with a slash will be treated as an
094         * <em>absolute</em> classpath resource, for example:
095         * {@code "/org/example/schema.sql"}. A path which references a
096         * URL (e.g., a path prefixed with
097         * {@link org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX classpath:},
098         * {@link org.springframework.util.ResourceUtils#FILE_URL_PREFIX file:},
099         * {@code http:}, etc.) will be loaded using the specified resource protocol.
100         * <h3>Default Script Detection</h3>
101         * <p>If no SQL scripts or {@link #statements} are specified, an attempt will
102         * be made to detect a <em>default</em> script depending on where this
103         * annotation is declared. If a default cannot be detected, an
104         * {@link IllegalStateException} will be thrown.
105         * <ul>
106         * <li><strong>class-level declaration</strong>: if the annotated test class
107         * is {@code com.example.MyTest}, the corresponding default script is
108         * {@code "classpath:com/example/MyTest.sql"}.</li>
109         * <li><strong>method-level declaration</strong>: if the annotated test
110         * method is named {@code testMethod()} and is defined in the class
111         * {@code com.example.MyTest}, the corresponding default script is
112         * {@code "classpath:com/example/MyTest.testMethod.sql"}.</li>
113         * </ul>
114         * @see #value
115         * @see #statements
116         */
117        @AliasFor("value")
118        String[] scripts() default {};
119
120        /**
121         * <em>Inlined SQL statements</em> to execute.
122         * <p>This attribute may be used in conjunction with or instead of
123         * {@link #scripts}.
124         * <h3>Ordering</h3>
125         * <p>Statements declared via this attribute will be executed after
126         * statements loaded from resource {@link #scripts}. If you wish to have
127         * inlined statements executed before scripts, simply declare multiple
128         * instances of {@code @Sql} on the same class or method.
129         * @since 4.2
130         * @see #scripts
131         */
132        String[] statements() default {};
133
134        /**
135         * When the SQL scripts and statements should be executed.
136         * <p>Defaults to {@link ExecutionPhase#BEFORE_TEST_METHOD BEFORE_TEST_METHOD}.
137         */
138        ExecutionPhase executionPhase() default ExecutionPhase.BEFORE_TEST_METHOD;
139
140        /**
141         * Local configuration for the SQL scripts and statements declared within
142         * this {@code @Sql} annotation.
143         * <p>See the class-level javadocs for {@link SqlConfig} for explanations of
144         * local vs. global configuration, inheritance, overrides, etc.
145         * <p>Defaults to an empty {@link SqlConfig @SqlConfig} instance.
146         */
147        SqlConfig config() default @SqlConfig();
148
149
150        /**
151         * Enumeration of <em>phases</em> that dictate when SQL scripts are executed.
152         */
153        enum ExecutionPhase {
154
155                /**
156                 * The configured SQL scripts and statements will be executed
157                 * <em>before</em> the corresponding test method.
158                 */
159                BEFORE_TEST_METHOD,
160
161                /**
162                 * The configured SQL scripts and statements will be executed
163                 * <em>after</em> the corresponding test method.
164                 */
165                AFTER_TEST_METHOD
166        }
167
168}