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.Retention; 023import java.lang.annotation.RetentionPolicy; 024import java.lang.annotation.Target; 025 026/** 027 * {@code @SqlConfig} defines metadata that is used to determine how to parse 028 * and execute SQL scripts configured via the {@link Sql @Sql} annotation. 029 * 030 * <h3>Configuration Scope</h3> 031 * <p>When declared as a class-level annotation on an integration test class, 032 * {@code @SqlConfig} serves as <strong><em>global</em></strong> configuration 033 * for all SQL scripts within the test class hierarchy. When declared directly 034 * via the {@link Sql#config config} attribute of the {@code @Sql} annotation, 035 * {@code @SqlConfig} serves as <strong><em>local</em></strong> configuration 036 * for the SQL scripts declared within the enclosing {@code @Sql} annotation. 037 * 038 * <h3>Default Values</h3> 039 * <p>Every attribute in {@code @SqlConfig} has an <em>implicit</em> default value 040 * which is documented in the javadocs of the corresponding attribute. Due to the 041 * rules defined for annotation attributes in the Java Language Specification, it 042 * is unfortunately not possible to assign a value of {@code null} to an annotation 043 * attribute. Thus, in order to support overrides of <em>inherited</em> global 044 * configuration, {@code @SqlConfig} attributes have an <em>explicit</em> 045 * {@code default} value of either {@code ""} for Strings, <code>{}</code> for 046 * arrays, or {@code DEFAULT} for Enums. This approach allows local declarations 047 * of {@code @SqlConfig} to selectively override individual attributes from global 048 * declarations of {@code @SqlConfig} by providing a value other than {@code ""}, 049 * <code>{}</code>, or {@code DEFAULT}. 050 * 051 * <h3>Inheritance and Overrides</h3> 052 * <p>Global {@code @SqlConfig} attributes are <em>inherited</em> whenever local 053 * {@code @SqlConfig} attributes do not supply an explicit value other than 054 * {@code ""}, <code>{}</code>, or {@code DEFAULT}. Explicit local configuration 055 * therefore <em>overrides</em> global configuration. 056 * 057 * @author Sam Brannen 058 * @author Tadaya Tsuyukubo 059 * @since 4.1 060 * @see Sql 061 */ 062@Target(ElementType.TYPE) 063@Retention(RetentionPolicy.RUNTIME) 064@Documented 065@Inherited 066public @interface SqlConfig { 067 068 /** 069 * The bean name of the {@link javax.sql.DataSource} against which the 070 * scripts should be executed. 071 * <p>The name is only required if there is more than one bean of type 072 * {@code DataSource} in the test's {@code ApplicationContext}. If there 073 * is only one such bean, it is not necessary to specify a bean name. 074 * <p>Defaults to an empty string, requiring that one of the following is 075 * true: 076 * <ol> 077 * <li>An explicit bean name is defined in a global declaration of 078 * {@code @SqlConfig}. 079 * <li>The data source can be retrieved from the transaction manager 080 * by using reflection to invoke a public method named 081 * {@code getDataSource()} on the transaction manager. 082 * <li>There is only one bean of type {@code DataSource} in the test's 083 * {@code ApplicationContext}.</li> 084 * <li>The {@code DataSource} to use is named {@code "dataSource"}.</li> 085 * </ol> 086 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveDataSource 087 */ 088 String dataSource() default ""; 089 090 /** 091 * The bean name of the {@link org.springframework.transaction.PlatformTransactionManager 092 * PlatformTransactionManager} that should be used to drive transactions. 093 * <p>The name is only used if there is more than one bean of type 094 * {@code PlatformTransactionManager} in the test's {@code ApplicationContext}. 095 * If there is only one such bean, it is not necessary to specify a bean name. 096 * <p>Defaults to an empty string, requiring that one of the following is 097 * true: 098 * <ol> 099 * <li>An explicit bean name is defined in a global declaration of 100 * {@code @SqlConfig}. 101 * <li>There is only one bean of type {@code PlatformTransactionManager} in 102 * the test's {@code ApplicationContext}.</li> 103 * <li>{@link org.springframework.transaction.annotation.TransactionManagementConfigurer 104 * TransactionManagementConfigurer} has been implemented to specify which 105 * {@code PlatformTransactionManager} bean should be used for annotation-driven 106 * transaction management.</li> 107 * <li>The {@code PlatformTransactionManager} to use is named 108 * {@code "transactionManager"}.</li> 109 * </ol> 110 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveTransactionManager 111 */ 112 String transactionManager() default ""; 113 114 /** 115 * The <em>mode</em> to use when determining whether SQL scripts should be 116 * executed within a transaction. 117 * <p>Defaults to {@link TransactionMode#DEFAULT DEFAULT}. 118 * <p>Can be set to {@link TransactionMode#ISOLATED} to ensure that the SQL 119 * scripts are executed in a new, isolated transaction that will be immediately 120 * committed. 121 * @see TransactionMode 122 */ 123 TransactionMode transactionMode() default TransactionMode.DEFAULT; 124 125 /** 126 * The encoding for the supplied SQL scripts, if different from the platform 127 * encoding. 128 * <p>An empty string denotes that the platform encoding should be used. 129 */ 130 String encoding() default ""; 131 132 /** 133 * The character string used to separate individual statements within the 134 * SQL scripts. 135 * <p>Implicitly defaults to {@code ";"} if not specified and falls back to 136 * {@code "\n"} as a last resort. 137 * <p>May be set to 138 * {@link org.springframework.jdbc.datasource.init.ScriptUtils#EOF_STATEMENT_SEPARATOR} 139 * to signal that each script contains a single statement without a 140 * separator. 141 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_STATEMENT_SEPARATOR 142 * @see org.springframework.jdbc.datasource.init.ScriptUtils#EOF_STATEMENT_SEPARATOR 143 */ 144 String separator() default ""; 145 146 /** 147 * The prefix that identifies single-line comments within the SQL scripts. 148 * <p>Implicitly defaults to {@code "--"}. 149 * <p>This attribute may <strong>not</strong> be used in conjunction with 150 * {@link #commentPrefixes commentPrefixes}, but it may be used instead of 151 * {@link #commentPrefixes commentPrefixes}. 152 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_COMMENT_PREFIX 153 * @see #commentPrefixes 154 */ 155 String commentPrefix() default ""; 156 157 /** 158 * The prefixes that identify single-line comments within the SQL scripts. 159 * <p>Implicitly defaults to {@code ["--"]}. 160 * <p>This attribute may <strong>not</strong> be used in conjunction with 161 * {@link #commentPrefix commentPrefix}, but it may be used instead of 162 * {@link #commentPrefix commentPrefix}. 163 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_COMMENT_PREFIXES 164 * @see #commentPrefix 165 * @since 5.2 166 */ 167 String[] commentPrefixes() default {}; 168 169 /** 170 * The start delimiter that identifies block comments within the SQL scripts. 171 * <p>Implicitly defaults to {@code "/*"}. 172 * @see #blockCommentEndDelimiter 173 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_BLOCK_COMMENT_START_DELIMITER 174 */ 175 String blockCommentStartDelimiter() default ""; 176 177 /** 178 * The end delimiter that identifies block comments within the SQL scripts. 179 * <p>Implicitly defaults to <code>"*/"</code>. 180 * @see #blockCommentStartDelimiter 181 * @see org.springframework.jdbc.datasource.init.ScriptUtils#DEFAULT_BLOCK_COMMENT_END_DELIMITER 182 */ 183 String blockCommentEndDelimiter() default ""; 184 185 /** 186 * The <em>mode</em> to use when an error is encountered while executing an 187 * SQL statement. 188 * <p>Defaults to {@link ErrorMode#DEFAULT DEFAULT}. 189 * @see ErrorMode 190 */ 191 ErrorMode errorMode() default ErrorMode.DEFAULT; 192 193 194 /** 195 * Enumeration of <em>modes</em> that dictate whether SQL scripts should be 196 * executed within a transaction and what the transaction propagation behavior 197 * should be. 198 */ 199 enum TransactionMode { 200 201 /** 202 * Indicates that the <em>default</em> transaction mode should be used. 203 * <p>The meaning of <em>default</em> depends on the context in which 204 * {@code @SqlConfig} is declared: 205 * <ul> 206 * <li>If {@code @SqlConfig} is declared <strong>only</strong> locally, 207 * the default transaction mode is {@link #INFERRED}.</li> 208 * <li>If {@code @SqlConfig} is declared globally, the default transaction 209 * mode is {@link #INFERRED}.</li> 210 * <li>If {@code @SqlConfig} is declared globally <strong>and</strong> 211 * locally, the default transaction mode for the local declaration is 212 * inherited from the global declaration.</li> 213 * </ul> 214 */ 215 DEFAULT, 216 217 /** 218 * Indicates that the transaction mode to use when executing SQL 219 * scripts should be <em>inferred</em> using the rules listed below. 220 * In the context of these rules, the term "<em>available</em>" 221 * means that the bean for the data source or transaction manager 222 * is either explicitly specified via a corresponding annotation 223 * attribute in {@code @SqlConfig} or discoverable via conventions. See 224 * {@link org.springframework.test.context.transaction.TestContextTransactionUtils TestContextTransactionUtils} 225 * for details on the conventions used to discover such beans in 226 * the {@code ApplicationContext}. 227 * 228 * <h4>Inference Rules</h4> 229 * <ol> 230 * <li>If neither a transaction manager nor a data source is 231 * available, an exception will be thrown. 232 * <li>If a transaction manager is not available but a data source 233 * is available, SQL scripts will be executed directly against the 234 * data source without a transaction. 235 * <li>If a transaction manager is available: 236 * <ul> 237 * <li>If a data source is not available, an attempt will be made 238 * to retrieve it from the transaction manager by using reflection 239 * to invoke a public method named {@code getDataSource()} on the 240 * transaction manager. If the attempt fails, an exception will be 241 * thrown. 242 * <li>Using the resolved transaction manager and data source, SQL 243 * scripts will be executed within an existing transaction if 244 * present; otherwise, scripts will be executed in a new transaction 245 * that will be immediately committed. An <em>existing</em> 246 * transaction will typically be managed by the 247 * {@link org.springframework.test.context.transaction.TransactionalTestExecutionListener TransactionalTestExecutionListener}. 248 * </ul> 249 * </ol> 250 * @see #ISOLATED 251 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveDataSource 252 * @see org.springframework.test.context.transaction.TestContextTransactionUtils#retrieveTransactionManager 253 */ 254 INFERRED, 255 256 /** 257 * Indicates that SQL scripts should always be executed in a new, 258 * <em>isolated</em> transaction that will be immediately committed. 259 * <p>In contrast to {@link #INFERRED}, this mode requires the 260 * presence of a transaction manager <strong>and</strong> a data 261 * source. 262 */ 263 ISOLATED 264 } 265 266 267 /** 268 * Enumeration of <em>modes</em> that dictate how errors are handled while 269 * executing SQL statements. 270 */ 271 enum ErrorMode { 272 273 /** 274 * Indicates that the <em>default</em> error mode should be used. 275 * <p>The meaning of <em>default</em> depends on the context in which 276 * {@code @SqlConfig} is declared: 277 * <ul> 278 * <li>If {@code @SqlConfig} is declared <strong>only</strong> locally, 279 * the default error mode is {@link #FAIL_ON_ERROR}.</li> 280 * <li>If {@code @SqlConfig} is declared globally, the default error 281 * mode is {@link #FAIL_ON_ERROR}.</li> 282 * <li>If {@code @SqlConfig} is declared globally <strong>and</strong> 283 * locally, the default error mode for the local declaration is 284 * inherited from the global declaration.</li> 285 * </rceLineNo">286 */ 287 DEFAULT, 288 289 /** 290 * Indicates that script execution will fail if an error is encountered. 291 * In other words, no errors should be ignored. 292 * <p>This is effectively the default error mode so that if a script 293 * is accidentally executed, it will fail fast if any SQL statement in 294 * the script results in an error. 295 * @see #CONTINUE_ON_ERROR 296 */ 297 FAIL_ON_ERROR, 298 299 /** 300 * Indicates that all errors in SQL scripts should be logged but not 301 * propagated as exceptions. 302 * <p>{@code CONTINUE_ON_ERROR} is the logical <em>opposite</em> of 303 * {@code FAIL_ON_ERROR} and a <em>superset</em> of {@code IGNORE_FAILED_DROPS}. 304 * @see #FAIL_ON_ERROR 305 * @see #IGNORE_FAILED_DROPS 306 */ 307 CONTINUE_ON_ERROR, 308 309 /** 310 * Indicates that failed SQL {@code DROP} statements can be ignored. 311 * <p>This is useful for a non-embedded database whose SQL dialect does 312 * not support an {@code IF EXISTS} clause in a {@code DROP} statement. 313 * @see #CONTINUE_ON_ERROR 314 */ 315 IGNORE_FAILED_DROPS 316 } 317 318}