Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
SqlExecMojo |
|
| 3.0952380952380953;3.095 | ||||
SqlExecMojo$1 |
|
| 3.0952380952380953;3.095 | ||||
SqlExecMojo$Transaction |
|
| 3.0952380952380953;3.095 |
1 | package org.codehaus.mojo.sql; | |
2 | ||
3 | /* | |
4 | * Licensed to the Apache Software Foundation (ASF) under one | |
5 | * or more contributor license agreements. See the NOTICE file | |
6 | * distributed with this work for additional information | |
7 | * regarding copyright ownership. The ASF licenses this file | |
8 | * to you under the Apache License, Version 2.0 (the | |
9 | * "License"); you may not use this file except in compliance | |
10 | * with the License. You may obtain a copy of the License at | |
11 | * | |
12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
13 | * | |
14 | * Unless required by applicable law or agreed to in writing, | |
15 | * software distributed under the License is distributed on an | |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
17 | * KIND, either express or implied. See the License for the | |
18 | * specific language governing permissions and limitations | |
19 | * under the License. | |
20 | */ | |
21 | ||
22 | import java.io.BufferedOutputStream; | |
23 | import java.io.BufferedReader; | |
24 | import java.io.File; | |
25 | import java.io.FileInputStream; | |
26 | import java.io.FileOutputStream; | |
27 | import java.io.FileReader; | |
28 | import java.io.IOException; | |
29 | import java.io.InputStream; | |
30 | import java.io.InputStreamReader; | |
31 | import java.io.OutputStream; | |
32 | import java.io.PrintStream; | |
33 | import java.io.Reader; | |
34 | import java.io.StringReader; | |
35 | import java.sql.Connection; | |
36 | import java.sql.Driver; | |
37 | import java.sql.ResultSet; | |
38 | import java.sql.ResultSetMetaData; | |
39 | import java.sql.SQLException; | |
40 | import java.sql.SQLWarning; | |
41 | import java.sql.Statement; | |
42 | import java.util.ArrayList; | |
43 | import java.util.Collections; | |
44 | import java.util.Enumeration; | |
45 | import java.util.List; | |
46 | import java.util.Properties; | |
47 | import java.util.StringTokenizer; | |
48 | import java.util.Vector; | |
49 | ||
50 | import org.apache.commons.io.IOUtils; | |
51 | import org.apache.commons.lang.StringEscapeUtils; | |
52 | import org.apache.maven.execution.MavenSession; | |
53 | import org.apache.maven.plugin.AbstractMojo; | |
54 | import org.apache.maven.plugin.MojoExecutionException; | |
55 | import org.apache.maven.project.MavenProject; | |
56 | import org.apache.maven.settings.Server; | |
57 | import org.apache.maven.settings.Settings; | |
58 | import org.apache.maven.shared.filtering.MavenFileFilter; | |
59 | import org.apache.maven.shared.filtering.MavenFileFilterRequest; | |
60 | import org.apache.maven.shared.filtering.MavenFilteringException; | |
61 | import org.codehaus.plexus.util.FileUtils; | |
62 | import org.codehaus.plexus.util.IOUtil; | |
63 | import org.codehaus.plexus.util.StringUtils; | |
64 | import org.springframework.core.io.DefaultResourceLoader; | |
65 | import org.springframework.core.io.Resource; | |
66 | import org.springframework.core.io.ResourceLoader; | |
67 | ||
68 | /** | |
69 | * Executes SQL against a database. | |
70 | * | |
71 | * @goal execute | |
72 | */ | |
73 | 0 | public class SqlExecMojo extends AbstractMojo { |
74 | ||
75 | /** | |
76 | * Call {@link #setOnError(String)} with this value to abort SQL command | |
77 | * execution if an error is found. | |
78 | */ | |
79 | public static final String ON_ERROR_ABORT = "abort"; | |
80 | ||
81 | /** | |
82 | * Call {@link #setOnError(String)} with this value to continue SQL command | |
83 | * execution until all commands have been attempted, then abort the build if | |
84 | * an SQL error occurred in any of the commands. | |
85 | */ | |
86 | public static final String ON_ERROR_ABORT_AFTER = "abortAfter"; | |
87 | ||
88 | /** | |
89 | * Call {@link #setOnError(String)} with this value to continue SQL command | |
90 | * execution if an error is found. | |
91 | */ | |
92 | public static final String ON_ERROR_CONTINUE = "continue"; | |
93 | ||
94 | /** | |
95 | * Call {@link #setOrderFile(String)} with this value to sort in ascendant | |
96 | * order the sql files. | |
97 | */ | |
98 | public static final String FILE_SORTING_ASC = "ascending"; | |
99 | ||
100 | /** | |
101 | * Call {@link #setOrderFile(String)} with this value to sort in descendant | |
102 | * order the sql files. | |
103 | */ | |
104 | public static final String FILE_SORTING_DSC = "descending"; | |
105 | ||
106 | // ////////////////////////// User Info /////////////////////////////////// | |
107 | ||
108 | /** | |
109 | * Database username. If not given, it will be looked up through | |
110 | * <code>settings.xml</code>'s server with <code>${settingsKey}</code> as | |
111 | * key. | |
112 | * | |
113 | * @since 1.0 | |
114 | * @parameter expression="${username}" | |
115 | */ | |
116 | private String username; | |
117 | ||
118 | /** | |
119 | * Database password. If not given, it will be looked up through | |
120 | * <code>settings.xml</code>'s server with <code>${settingsKey}</code> as | |
121 | * key. | |
122 | * | |
123 | * @since 1.0 | |
124 | * @parameter expression="${password}" | |
125 | */ | |
126 | private String password; | |
127 | ||
128 | /** | |
129 | * Ignore the password and use anonymous access. This may be useful for | |
130 | * databases like MySQL which do not allow empty password parameters in the | |
131 | * connection initialization. | |
132 | * | |
133 | * @since 1.4 | |
134 | * @parameter default-value="false" | |
135 | */ | |
136 | private boolean enableAnonymousPassword; | |
137 | ||
138 | /** | |
139 | * Additional key=value pairs separated by comma to be passed into JDBC | |
140 | * driver. | |
141 | * | |
142 | * @since 1.0 | |
143 | * @parameter expression="${driverProperties}" default-value = "" | |
144 | */ | |
145 | private String driverProperties; | |
146 | ||
147 | /** | |
148 | * @parameter expression="${settings}" | |
149 | * @required | |
150 | * @since 1.0 | |
151 | * @readonly | |
152 | */ | |
153 | private Settings settings; | |
154 | ||
155 | /** | |
156 | * Server's <code>id</code> in <code>settings.xml</code> to look up username | |
157 | * and password. Defaults to <code>${url}</code> if not given. | |
158 | * | |
159 | * @since 1.0 | |
160 | * @parameter expression="${settingsKey}" | |
161 | */ | |
162 | private String settingsKey; | |
163 | ||
164 | /** | |
165 | * Skip execution when there is an error obtaining a connection. This is a | |
166 | * special case to support databases, such as embedded Derby, that can | |
167 | * shutdown the database via the URL (i.e. <code>shutdown=true</code>). | |
168 | * | |
169 | * @since 1.1 | |
170 | * @parameter expression="${skipOnConnectionError}" default-value="false" | |
171 | */ | |
172 | private boolean skipOnConnectionError; | |
173 | ||
174 | /** | |
175 | * Setting this parameter to <code>true</code> will force the execution of | |
176 | * this mojo, even if it would get skipped usually. | |
177 | * | |
178 | * @parameter expression="${forceOpenJpaExecution}" default-value=false | |
179 | * @required | |
180 | */ | |
181 | private boolean forceMojoExecution; | |
182 | ||
183 | /** | |
184 | * The Maven Project Object | |
185 | * | |
186 | * @parameter default-value="${project}" | |
187 | * @required | |
188 | * @readonly | |
189 | */ | |
190 | protected MavenProject project; | |
191 | ||
192 | /** | |
193 | * @parameter default-value="${session}" | |
194 | * @required | |
195 | * @readonly | |
196 | */ | |
197 | private MavenSession mavenSession; | |
198 | ||
199 | // ////////////////////////////// Source info ///////////////////////////// | |
200 | ||
201 | /** | |
202 | * SQL input commands separated by <code>${delimiter}</code>. | |
203 | * | |
204 | * @since 1.0 | |
205 | * @parameter expression="${sqlCommand}" default-value="" | |
206 | */ | |
207 | 0 | private String sqlCommand = ""; |
208 | ||
209 | /** | |
210 | * List of files containing SQL statements to load. | |
211 | * | |
212 | * @since 1.0 | |
213 | * @parameter | |
214 | */ | |
215 | private File[] srcFiles; | |
216 | ||
217 | /** | |
218 | * List of resources containing SQL statements | |
219 | * | |
220 | * @since 1.5 | |
221 | * @parameter | |
222 | */ | |
223 | private String[] resourceLocations; | |
224 | ||
225 | /** | |
226 | * File(s) containing SQL statements to load. | |
227 | * | |
228 | * @since 1.0 | |
229 | * @parameter | |
230 | */ | |
231 | private Fileset fileset; | |
232 | ||
233 | /** | |
234 | * When <code>true</code>, skip the execution. | |
235 | * | |
236 | * @since 1.0 | |
237 | * @parameter default-value="false" | |
238 | */ | |
239 | private boolean skip; | |
240 | ||
241 | // //////////////////////////////// Database info ///////////////////////// | |
242 | /** | |
243 | * Database URL. | |
244 | * | |
245 | * @parameter expression="${url}" | |
246 | * @required | |
247 | * @since 1.0-beta-1 | |
248 | */ | |
249 | private String url; | |
250 | ||
251 | /** | |
252 | * Database driver classname. | |
253 | * | |
254 | * @since 1.0 | |
255 | * @parameter expression="${driver}" | |
256 | * @required | |
257 | */ | |
258 | private String driver; | |
259 | ||
260 | // //////////////////////////// Operation Configuration //////////////////// | |
261 | /** | |
262 | * Set to <code>true</code> to execute none-transactional SQL. | |
263 | * | |
264 | * @since 1.0 | |
265 | * @parameter expression="${autocommit}" default-value="false" | |
266 | */ | |
267 | private boolean autocommit; | |
268 | ||
269 | /** | |
270 | * Action to perform if an error is found. Possible values are | |
271 | * <code>abort</code> and <code>continue</code>. | |
272 | * | |
273 | * @since 1.0 | |
274 | * @parameter expression="${onError}" default-value="abort" | |
275 | */ | |
276 | 0 | private String onError = ON_ERROR_ABORT; |
277 | ||
278 | // //////////////////////////// Parser Configuration //////////////////// | |
279 | ||
280 | /** | |
281 | * Set the delimiter that separates SQL statements. | |
282 | * | |
283 | * @since 1.0 | |
284 | * @parameter expression="${delimiter}" default-value=";" | |
285 | */ | |
286 | 0 | private String delimiter = ";"; |
287 | ||
288 | /** | |
289 | * <p> | |
290 | * The delimiter type takes two values - "normal" and "row". Normal means | |
291 | * that any occurrence of the delimiter terminate the SQL command whereas | |
292 | * with row, only a line containing just the delimiter is recognized as the | |
293 | * end of the command. | |
294 | * </p> | |
295 | * <p> | |
296 | * For example, set this to "go" and delimiterType to "row" for Sybase ASE | |
297 | * or MS SQL Server. | |
298 | * </p> | |
299 | * | |
300 | * @since 1.2 | |
301 | * @parameter expression="${delimiterType}" default-value="normal" | |
302 | */ | |
303 | 0 | private String delimiterType = DelimiterType.NORMAL; |
304 | ||
305 | /** | |
306 | * Set the order in which the SQL files will be executed. Possible values | |
307 | * are <code>ascending</code> and <code>descending</code>. Any other value | |
308 | * means that no sorting will be performed. | |
309 | * | |
310 | * @since 1.1 | |
311 | * @parameter expression="${orderFile}" | |
312 | */ | |
313 | 0 | private String orderFile = null; |
314 | ||
315 | /** | |
316 | * When <code>true</code>, the whole SQL content in <code>sqlCommand</code>, | |
317 | * <code>srcFiles</code> and <code>fileset</code> are sent directly to JDBC | |
318 | * in one SQL statement. This option is for executing database stored | |
319 | * procedures/functions. | |
320 | * | |
321 | * @deprecated used <i>delimiterType<i> instead. | |
322 | * @since 1.1 | |
323 | * @parameter expression="${enableBlockMode}" | |
324 | */ | |
325 | ||
326 | 0 | private boolean enableBlockMode = false; |
327 | ||
328 | /** | |
329 | * Keep the format of an SQL block. | |
330 | * | |
331 | * @since 1.1 | |
332 | * @parameter expression="${keepFormat}" default-value="false" | |
333 | */ | |
334 | 0 | private boolean keepFormat = false; |
335 | ||
336 | // ///////////////////////////////////////////////////////////////////////////////////// | |
337 | /** | |
338 | * Print SQL results. | |
339 | * | |
340 | * @parameter | |
341 | * @since 1.3 | |
342 | */ | |
343 | 0 | private boolean printResultSet = false; |
344 | ||
345 | /** | |
346 | * Print header columns. | |
347 | */ | |
348 | 0 | private boolean showheaders = true; |
349 | ||
350 | /** | |
351 | * Dump the SQL exection's output to a file. Default is stdout. | |
352 | * | |
353 | * @parameter | |
354 | * @since 1.3 | |
355 | */ | |
356 | private File outputFile; | |
357 | ||
358 | /** | |
359 | * @parameter default-value="," | |
360 | * @since 1.4 | |
361 | */ | |
362 | private String outputDelimiter; | |
363 | ||
364 | /** | |
365 | * Encoding to use when reading SQL statements from a file. | |
366 | * | |
367 | * @parameter expression="${encoding}" default-value= | |
368 | * "${project.build.sourceEncoding}" | |
369 | * @since 1.1 | |
370 | */ | |
371 | 0 | private String encoding = ""; |
372 | ||
373 | /** | |
374 | * Append to an existing file or overwrite it? | |
375 | */ | |
376 | 0 | private boolean append = false; |
377 | ||
378 | /** | |
379 | * Argument to Statement.setEscapeProcessing If you want the driver to use | |
380 | * regular SQL syntax then set this to false. | |
381 | * | |
382 | * @since 1.4 | |
383 | * @parameter expression="${escapeProcessing}" default-value="true" | |
384 | */ | |
385 | 0 | private boolean escapeProcessing = true; |
386 | ||
387 | // //////////////////////////////// Internal | |
388 | // properties////////////////////// | |
389 | ||
390 | /** | |
391 | * number of successful executed statements | |
392 | */ | |
393 | 0 | private int successfulStatements = 0; |
394 | ||
395 | /** | |
396 | * number of total executed statements | |
397 | */ | |
398 | 0 | private int totalStatements = 0; |
399 | ||
400 | /** | |
401 | * Database connection | |
402 | */ | |
403 | 0 | private Connection conn = null; |
404 | ||
405 | /** | |
406 | * SQL statement | |
407 | */ | |
408 | 0 | private Statement statement = null; |
409 | ||
410 | /** | |
411 | * SQL transactions to perform | |
412 | */ | |
413 | 0 | private Vector<Transaction> transactions = new Vector<Transaction>(); |
414 | ||
415 | /** | |
416 | * @component role="org.apache.maven.shared.filtering.MavenFileFilter" | |
417 | * @since 1.4 | |
418 | */ | |
419 | private MavenFileFilter fileFilter; | |
420 | ||
421 | /** | |
422 | * Set to true if you want to filter the srcFiles using system-, user- and | |
423 | * project properties | |
424 | * | |
425 | * @parameter | |
426 | * @since 1.4 | |
427 | */ | |
428 | private boolean enableFiltering; | |
429 | ||
430 | /** | |
431 | * Interpolator especially for braceless expressions | |
432 | */ | |
433 | // private Interpolator interpolator = new | |
434 | // RegexBasedInterpolator("\\$([^\\s;)]+?)", "(?=[\\s;)])"); | |
435 | ||
436 | /** | |
437 | * Add a SQL transaction to execute | |
438 | * | |
439 | * @return a new SqlExecMojo.Transaction | |
440 | */ | |
441 | public Transaction createTransaction() { | |
442 | 0 | Transaction t = new Transaction(); |
443 | 0 | transactions.addElement(t); |
444 | 0 | return t; |
445 | } | |
446 | ||
447 | /** | |
448 | * Set an inline SQL command to execute. NB: Properties are not expanded in | |
449 | * this text. | |
450 | * | |
451 | * @param sql | |
452 | * the sql statement to add | |
453 | */ | |
454 | public void addText(String sql) { | |
455 | 0 | this.sqlCommand += sql; |
456 | 0 | } |
457 | ||
458 | /** | |
459 | * Set the file encoding to use on the SQL files read in | |
460 | * | |
461 | * @param encoding | |
462 | * the encoding to use on the files | |
463 | */ | |
464 | public void setEncoding(String encoding) { | |
465 | 0 | this.encoding = encoding; |
466 | 0 | } |
467 | ||
468 | /** | |
469 | * Set the delimiter that separates SQL statements. Defaults to | |
470 | * ";"; | |
471 | * | |
472 | * @param delimiter | |
473 | * the new delimiter | |
474 | */ | |
475 | public void setDelimiter(String delimiter) { | |
476 | 0 | this.delimiter = delimiter; |
477 | 0 | } |
478 | ||
479 | /** | |
480 | * Set the delimiter type: "normal" or "row" (default "normal"). | |
481 | * | |
482 | * @param delimiterType | |
483 | * the new delimiterType | |
484 | */ | |
485 | public void setDelimiterType(String delimiterType) { | |
486 | 0 | this.delimiterType = delimiterType; |
487 | 0 | } |
488 | ||
489 | /** | |
490 | * Print result sets from the statements; optional, default false | |
491 | * | |
492 | * @param print | |
493 | * <code>true</code> to print the resultset, otherwise | |
494 | * <code>false</code> | |
495 | * @deprecated typo, use setPrintResultSet() | |
496 | */ | |
497 | public void setPrintResutlSet(boolean print) { | |
498 | 0 | setPrintResultSet(print); |
499 | 0 | } |
500 | ||
501 | /** | |
502 | * Print result sets from the statements; optional, default false | |
503 | * | |
504 | * @param print | |
505 | * <code>true</code> to print the resultset, otherwise | |
506 | * <code>false</code> | |
507 | */ | |
508 | public void setPrintResultSet(boolean print) { | |
509 | 0 | this.printResultSet = print; |
510 | 0 | } |
511 | ||
512 | /** | |
513 | * Print headers for result sets from the statements; optional, default | |
514 | * true. | |
515 | * | |
516 | * @param showheaders | |
517 | * <code>true</code> to show the headers, otherwise | |
518 | * <code>false</code> | |
519 | */ | |
520 | public void setShowheaders(boolean showheaders) { | |
521 | 0 | this.showheaders = showheaders; |
522 | 0 | } |
523 | ||
524 | /** | |
525 | * Set the output file; | |
526 | * | |
527 | * @param output | |
528 | * the output file | |
529 | */ | |
530 | public void setOutputFile(File output) { | |
531 | 0 | this.outputFile = output; |
532 | 0 | } |
533 | ||
534 | /** | |
535 | * whether output should be appended to or overwrite an existing file. | |
536 | * Defaults to false. | |
537 | * | |
538 | * @param append | |
539 | * <code>true</code> to append, otherwise <code>false</code> to | |
540 | * overwrite | |
541 | */ | |
542 | public void setAppend(boolean append) { | |
543 | 0 | this.append = append; |
544 | 0 | } |
545 | ||
546 | /** | |
547 | * whether or not format should be preserved. Defaults to false. | |
548 | * | |
549 | * @param keepformat | |
550 | * The keepformat to set | |
551 | */ | |
552 | public void setKeepFormat(boolean keepformat) { | |
553 | 0 | this.keepFormat = keepformat; |
554 | 0 | } |
555 | ||
556 | /** | |
557 | * Set escape processing for statements. | |
558 | * | |
559 | * @param enable | |
560 | * <code>true</code> to escape, otherwiser <code>false</code> | |
561 | */ | |
562 | public void setEscapeProcessing(boolean enable) { | |
563 | 0 | escapeProcessing = enable; |
564 | 0 | } |
565 | ||
566 | /** | |
567 | * <p> | |
568 | * Determine if the mojo execution should get skipped. | |
569 | * </p> | |
570 | * This is the case if: | |
571 | * <ul> | |
572 | * <li>{@link #skip} is <code>true</code></li> | |
573 | * <li>if the mojo gets executed on a project with packaging type 'pom' and | |
574 | * {@link #forceMojoExecution} is <code>false</code></li> | |
575 | * </ul> | |
576 | * | |
577 | * @return <code>true</code> if the mojo execution should be skipped. | |
578 | */ | |
579 | protected boolean skipMojo() { | |
580 | 0 | if (skip) { |
581 | 0 | getLog().info("Skip sql execution"); |
582 | 0 | return true; |
583 | } | |
584 | ||
585 | 0 | if (!forceMojoExecution && project != null && "pom".equals(project.getPackaging())) { |
586 | 0 | getLog().info("Skipping sql execution for project with packaging type 'pom'"); |
587 | 0 | return true; |
588 | } | |
589 | ||
590 | 0 | return false; |
591 | } | |
592 | ||
593 | /** | |
594 | * Load the sql file and then execute it | |
595 | * | |
596 | * @throws MojoExecutionException | |
597 | */ | |
598 | public void execute() throws MojoExecutionException { | |
599 | ||
600 | 0 | if (skipMojo()) { |
601 | 0 | return; |
602 | } | |
603 | ||
604 | 0 | successfulStatements = 0; |
605 | ||
606 | 0 | totalStatements = 0; |
607 | ||
608 | 0 | loadUserInfoFromSettings(); |
609 | ||
610 | 0 | addCommandToTransactions(); |
611 | ||
612 | 0 | addFilesToTransactions(); |
613 | ||
614 | 0 | addFileSetToTransactions(); |
615 | ||
616 | 0 | addResourcesToTransactions(); |
617 | ||
618 | 0 | sortTransactions(); |
619 | ||
620 | try { | |
621 | 0 | conn = getConnection(); |
622 | 0 | } catch (SQLException e) { |
623 | 0 | if (!this.skipOnConnectionError) { |
624 | 0 | throw new MojoExecutionException(e.getMessage(), e); |
625 | } else { | |
626 | // error on get connection and user asked to skip the rest | |
627 | 0 | return; |
628 | } | |
629 | 0 | } |
630 | ||
631 | try { | |
632 | 0 | statement = conn.createStatement(); |
633 | 0 | statement.setEscapeProcessing(escapeProcessing); |
634 | ||
635 | 0 | PrintStream out = System.out; |
636 | try { | |
637 | 0 | if (outputFile != null) { |
638 | 0 | getLog().debug("Opening PrintStream to output file " + outputFile); |
639 | 0 | out = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile.getAbsolutePath(), |
640 | append))); | |
641 | } | |
642 | ||
643 | // Process all transactions | |
644 | 0 | for (Enumeration<Transaction> e = transactions.elements(); e.hasMoreElements();) { |
645 | 0 | Transaction t = e.nextElement(); |
646 | ||
647 | 0 | t.runTransaction(out); |
648 | ||
649 | 0 | if (!autocommit) { |
650 | 0 | getLog().debug("Committing transaction"); |
651 | 0 | conn.commit(); |
652 | } | |
653 | 0 | } |
654 | } finally { | |
655 | 0 | if (out != null && out != System.out) { |
656 | 0 | out.close(); |
657 | } | |
658 | } | |
659 | 0 | } catch (IOException e) { |
660 | 0 | throw new MojoExecutionException(e.getMessage(), e); |
661 | 0 | } catch (SQLException e) { |
662 | 0 | if (!autocommit && conn != null && ON_ERROR_ABORT.equalsIgnoreCase(getOnError())) { |
663 | try { | |
664 | 0 | conn.rollback(); |
665 | 0 | } catch (SQLException ex) { |
666 | // ignore | |
667 | 0 | } |
668 | } | |
669 | 0 | throw new MojoExecutionException(e.getMessage(), e); |
670 | } finally { | |
671 | 0 | try { |
672 | 0 | if (statement != null) { |
673 | 0 | statement.close(); |
674 | } | |
675 | 0 | if (conn != null) { |
676 | 0 | conn.close(); |
677 | } | |
678 | 0 | } catch (SQLException ex) { |
679 | // ignore | |
680 | 0 | } |
681 | 0 | } |
682 | ||
683 | 0 | getLog().info( |
684 | getSuccessfulStatements() + " of " + getTotalStatements() + " SQL statements executed successfully"); | |
685 | ||
686 | 0 | if (ON_ERROR_ABORT_AFTER.equalsIgnoreCase(getOnError()) && totalStatements != successfulStatements) { |
687 | 0 | throw new MojoExecutionException("Some SQL statements failed to execute"); |
688 | } | |
689 | ||
690 | 0 | } |
691 | ||
692 | /** | |
693 | * Add sql command to transactions list. | |
694 | * | |
695 | */ | |
696 | private void addCommandToTransactions() { | |
697 | 0 | createTransaction().addText(sqlCommand.trim()); |
698 | 0 | } |
699 | ||
700 | /** | |
701 | * Add user sql fileset to transation list | |
702 | * | |
703 | */ | |
704 | private void addFileSetToTransactions() { | |
705 | String[] includedFiles; | |
706 | 0 | if (fileset != null) { |
707 | 0 | fileset.scan(); |
708 | 0 | includedFiles = fileset.getIncludedFiles(); |
709 | } else { | |
710 | 0 | includedFiles = new String[0]; |
711 | } | |
712 | ||
713 | 0 | for (int j = 0; j < includedFiles.length; j++) { |
714 | 0 | createTransaction().setSrc(new File(fileset.getBasedir(), includedFiles[j])); |
715 | } | |
716 | 0 | } |
717 | ||
718 | protected Resource[] getResources(String[] locations) throws MojoExecutionException { | |
719 | 0 | if (locations == null || locations.length == 0) { |
720 | 0 | return new Resource[] {}; |
721 | } | |
722 | 0 | ResourceLoader loader = new DefaultResourceLoader(); |
723 | 0 | List<Resource> resources = new ArrayList<Resource>(); |
724 | 0 | for (int i = 0; i < locations.length; i++) { |
725 | 0 | String location = locations[i]; |
726 | // Skip it if the location is empty | |
727 | 0 | if (StringUtils.isEmpty(location)) { |
728 | 0 | continue; |
729 | } | |
730 | 0 | Resource resource = loader.getResource(location); |
731 | 0 | if (!resource.exists()) { |
732 | // The location was not empty, but we couldn't find it | |
733 | 0 | throw new MojoExecutionException("Resource " + location + " was not found"); |
734 | } | |
735 | 0 | resources.add(resource); |
736 | } | |
737 | 0 | return resources.toArray(new Resource[resources.size()]); |
738 | } | |
739 | ||
740 | protected void copy(Resource resource, File file) throws IOException { | |
741 | 0 | InputStream in = resource.getInputStream(); |
742 | 0 | OutputStream out = new FileOutputStream(file); |
743 | 0 | IOUtils.copyLarge(in, out); |
744 | 0 | } |
745 | ||
746 | /** | |
747 | * Add user input of srcFiles to transaction list. | |
748 | * | |
749 | * @throws MojoExecutionException | |
750 | */ | |
751 | private void addResourcesToTransactions() throws MojoExecutionException { | |
752 | 0 | String[] locations = getResourceLocations(); |
753 | 0 | Resource[] resources = getResources(locations); |
754 | ||
755 | 0 | MavenFileFilterRequest request = new MavenFileFilterRequest(); |
756 | 0 | request.setEncoding(encoding); |
757 | 0 | request.setMavenSession(mavenSession); |
758 | 0 | request.setMavenProject(project); |
759 | 0 | request.setFiltering(enableFiltering); |
760 | 0 | for (int i = 0; i < resources.length; i++) { |
761 | 0 | Resource resource = resources[i]; |
762 | 0 | String filename = resource.getFilename(); |
763 | 0 | String basename = FileUtils.basename(filename); |
764 | 0 | String extension = FileUtils.extension(filename); |
765 | 0 | File sourceFile = FileUtils.createTempFile(basename, extension, null); |
766 | ||
767 | try { | |
768 | 0 | copy(resource, sourceFile); |
769 | 0 | } catch (IOException e) { |
770 | 0 | throw new MojoExecutionException("Error copying resource " + resource + "to a temp file", e); |
771 | 0 | } |
772 | ||
773 | 0 | File targetFile = FileUtils.createTempFile(basename, extension, null); |
774 | 0 | if (!getLog().isDebugEnabled()) { |
775 | 0 | targetFile.deleteOnExit(); |
776 | 0 | sourceFile.deleteOnExit(); |
777 | } | |
778 | ||
779 | 0 | request.setFrom(sourceFile); |
780 | 0 | request.setTo(targetFile); |
781 | ||
782 | try { | |
783 | 0 | fileFilter.copyFile(request); |
784 | 0 | } catch (MavenFilteringException e) { |
785 | 0 | throw new MojoExecutionException(e.getMessage()); |
786 | 0 | } |
787 | ||
788 | 0 | createTransaction().setSrc(targetFile); |
789 | } | |
790 | 0 | } |
791 | ||
792 | /** | |
793 | * Add user input of srcFiles to transaction list. | |
794 | * | |
795 | * @throws MojoExecutionException | |
796 | */ | |
797 | private void addFilesToTransactions() throws MojoExecutionException { | |
798 | 0 | File[] files = getSrcFiles(); |
799 | ||
800 | 0 | MavenFileFilterRequest request = new MavenFileFilterRequest(); |
801 | 0 | request.setEncoding(encoding); |
802 | 0 | request.setMavenSession(mavenSession); |
803 | 0 | request.setMavenProject(project); |
804 | 0 | request.setFiltering(enableFiltering); |
805 | 0 | for (int i = 0; files != null && i < files.length; ++i) { |
806 | 0 | if (files[i] != null && !files[i].exists()) { |
807 | 0 | throw new MojoExecutionException(files[i].getPath() + " not found."); |
808 | } | |
809 | ||
810 | 0 | File sourceFile = files[i]; |
811 | 0 | String basename = FileUtils.basename(sourceFile.getName()); |
812 | 0 | String extension = FileUtils.extension(sourceFile.getName()); |
813 | 0 | File targetFile = FileUtils.createTempFile(basename, extension, null); |
814 | 0 | if (!getLog().isDebugEnabled()) { |
815 | 0 | targetFile.deleteOnExit(); |
816 | } | |
817 | ||
818 | 0 | request.setFrom(sourceFile); |
819 | 0 | request.setTo(targetFile); |
820 | ||
821 | try { | |
822 | 0 | fileFilter.copyFile(request); |
823 | 0 | } catch (MavenFilteringException e) { |
824 | 0 | throw new MojoExecutionException(e.getMessage()); |
825 | 0 | } |
826 | ||
827 | 0 | createTransaction().setSrc(targetFile); |
828 | } | |
829 | 0 | } |
830 | ||
831 | /** | |
832 | * Sort the transaction list. | |
833 | */ | |
834 | private void sortTransactions() { | |
835 | 0 | if (FILE_SORTING_ASC.equalsIgnoreCase(this.orderFile)) { |
836 | 0 | Collections.sort(transactions); |
837 | 0 | } else if (FILE_SORTING_DSC.equalsIgnoreCase(this.orderFile)) { |
838 | 0 | Collections.sort(transactions, Collections.reverseOrder()); |
839 | } | |
840 | 0 | } |
841 | ||
842 | /** | |
843 | * Load username password from settings if user has not set them in JVM | |
844 | * properties | |
845 | * | |
846 | * @throws MojoExecutionException | |
847 | */ | |
848 | private void loadUserInfoFromSettings() throws MojoExecutionException { | |
849 | 0 | if (this.settingsKey == null) { |
850 | 0 | this.settingsKey = getUrl(); |
851 | } | |
852 | ||
853 | 0 | if ((getUsername() == null || getPassword() == null) && (settings != null)) { |
854 | 0 | Server server = this.settings.getServer(this.settingsKey); |
855 | ||
856 | 0 | if (server != null) { |
857 | 0 | if (getUsername() == null) { |
858 | 0 | setUsername(server.getUsername()); |
859 | } | |
860 | ||
861 | 0 | if (getPassword() == null) { |
862 | 0 | setPassword(server.getPassword()); |
863 | } | |
864 | } | |
865 | } | |
866 | ||
867 | 0 | if (getUsername() == null) { |
868 | // allow emtpy username | |
869 | 0 | setUsername(""); |
870 | } | |
871 | ||
872 | 0 | if (getPassword() == null) { |
873 | // allow emtpy password | |
874 | 0 | setPassword(""); |
875 | } | |
876 | 0 | } |
877 | ||
878 | /** | |
879 | * Creates a new Connection as using the driver, url, userid and password | |
880 | * specified. | |
881 | * | |
882 | * The calling method is responsible for closing the connection. | |
883 | * | |
884 | * @return Connection the newly created connection. | |
885 | * @throws MojoExecutionException | |
886 | * if the UserId/Password/Url is not set or there is no suitable | |
887 | * driver or the driver fails to load. | |
888 | * @throws SQLException | |
889 | * if there is problem getting connection with valid url | |
890 | * | |
891 | */ | |
892 | private Connection getConnection() throws MojoExecutionException, SQLException { | |
893 | 0 | getLog().debug("connecting to " + getUrl()); |
894 | 0 | Properties info = new Properties(); |
895 | 0 | info.put("user", getUsername()); |
896 | ||
897 | 0 | if (!enableAnonymousPassword) { |
898 | 0 | info.put("password", getPassword()); |
899 | } | |
900 | ||
901 | 0 | info.putAll(this.getDriverProperties()); |
902 | ||
903 | 0 | Driver driverInstance = null; |
904 | ||
905 | try { | |
906 | 0 | Class<?> dc = Class.forName(getDriver()); |
907 | 0 | driverInstance = (Driver) dc.newInstance(); |
908 | 0 | } catch (ClassNotFoundException e) { |
909 | 0 | throw new MojoExecutionException("Driver class not found: " + getDriver(), e); |
910 | 0 | } catch (Exception e) { |
911 | 0 | throw new MojoExecutionException("Failure loading driver: " + getDriver(), e); |
912 | 0 | } |
913 | ||
914 | 0 | Connection conn = driverInstance.connect(getUrl(), info); |
915 | ||
916 | 0 | if (conn == null) { |
917 | // Driver doesn't understand the URL | |
918 | 0 | throw new SQLException("No suitable Driver for " + getUrl()); |
919 | } | |
920 | ||
921 | 0 | conn.setAutoCommit(autocommit); |
922 | 0 | return conn; |
923 | } | |
924 | ||
925 | /** | |
926 | * parse driverProperties into Properties set | |
927 | * | |
928 | * @return the driver properties | |
929 | * @throws MojoExecutionException | |
930 | */ | |
931 | protected Properties getDriverProperties() throws MojoExecutionException { | |
932 | 0 | Properties properties = new Properties(); |
933 | ||
934 | 0 | if (!StringUtils.isEmpty(this.driverProperties)) { |
935 | 0 | String[] tokens = StringUtils.split(this.driverProperties, ","); |
936 | 0 | for (int i = 0; i < tokens.length; ++i) { |
937 | 0 | String[] keyValueTokens = StringUtils.split(tokens[i].trim(), "="); |
938 | 0 | if (keyValueTokens.length != 2) { |
939 | 0 | throw new MojoExecutionException("Invalid JDBC Driver properties: " + this.driverProperties); |
940 | } | |
941 | ||
942 | 0 | properties.setProperty(keyValueTokens[0], keyValueTokens[1]); |
943 | ||
944 | } | |
945 | } | |
946 | ||
947 | 0 | return properties; |
948 | } | |
949 | ||
950 | /** | |
951 | * read in lines and execute them | |
952 | * | |
953 | * @param reader | |
954 | * the reader | |
955 | * @param out | |
956 | * the outputstream | |
957 | * @throws SQLException | |
958 | * @throws IOException | |
959 | */ | |
960 | private void runStatements(Reader reader, PrintStream out) throws SQLException, IOException { | |
961 | String line; | |
962 | ||
963 | 0 | if (enableBlockMode) { |
964 | // no need to parse the content, ship it directly to jdbc in one sql | |
965 | // statement | |
966 | 0 | line = IOUtil.toString(reader); |
967 | 0 | execSQL(line, out); |
968 | 0 | return; |
969 | } | |
970 | ||
971 | 0 | StringBuffer sql = new StringBuffer(); |
972 | ||
973 | 0 | BufferedReader in = new BufferedReader(reader); |
974 | ||
975 | 0 | while ((line = in.readLine()) != null) { |
976 | 0 | if (!keepFormat) { |
977 | 0 | line = line.trim(); |
978 | } | |
979 | ||
980 | 0 | if (!keepFormat) { |
981 | 0 | if (line.startsWith("//")) { |
982 | 0 | continue; |
983 | } | |
984 | 0 | if (line.startsWith("--")) { |
985 | 0 | continue; |
986 | } | |
987 | 0 | StringTokenizer st = new StringTokenizer(line); |
988 | 0 | if (st.hasMoreTokens()) { |
989 | 0 | String token = st.nextToken(); |
990 | 0 | if ("REM".equalsIgnoreCase(token)) { |
991 | 0 | continue; |
992 | } | |
993 | } | |
994 | } | |
995 | ||
996 | 0 | if (!keepFormat) { |
997 | 0 | sql.append(" ").append(line); |
998 | } else { | |
999 | 0 | sql.append("\n").append(line); |
1000 | } | |
1001 | ||
1002 | // SQL defines "--" as a comment to EOL | |
1003 | // and in Oracle it may contain a hint | |
1004 | // so we cannot just remove it, instead we must end it | |
1005 | 0 | if (!keepFormat) { |
1006 | 0 | if (SqlSplitter.containsSqlEnd(line, delimiter) == SqlSplitter.NO_END) { |
1007 | 0 | sql.append("\n"); |
1008 | } | |
1009 | } | |
1010 | ||
1011 | 0 | if ((delimiterType.equals(DelimiterType.NORMAL) && SqlSplitter.containsSqlEnd(line, delimiter) > 0) |
1012 | || (delimiterType.equals(DelimiterType.ROW) && line.trim().equals(delimiter))) { | |
1013 | 0 | execSQL(sql.substring(0, sql.length() - delimiter.length()), out); |
1014 | 0 | sql.setLength(0); // clean buffer |
1015 | } | |
1016 | } | |
1017 | ||
1018 | // Catch any statements not followed by ; | |
1019 | 0 | if (!sql.toString().equals("")) { |
1020 | 0 | execSQL(sql.toString(), out); |
1021 | } | |
1022 | 0 | } |
1023 | ||
1024 | /** | |
1025 | * Exec the sql statement. | |
1026 | * | |
1027 | * @param sql | |
1028 | * query to execute | |
1029 | * @param out | |
1030 | * the outputstream | |
1031 | */ | |
1032 | private void execSQL(String sql, PrintStream out) throws SQLException { | |
1033 | // Check and ignore empty statements | |
1034 | 0 | if ("".equals(sql.trim())) { |
1035 | 0 | return; |
1036 | } | |
1037 | ||
1038 | 0 | ResultSet resultSet = null; |
1039 | try { | |
1040 | 0 | totalStatements++; |
1041 | 0 | getLog().debug("SQL: " + sql); |
1042 | ||
1043 | boolean ret; | |
1044 | 0 | int updateCountTotal = 0; |
1045 | ||
1046 | 0 | ret = statement.execute(sql); |
1047 | do { | |
1048 | 0 | if (!ret) { |
1049 | 0 | int updateCount = statement.getUpdateCount(); |
1050 | 0 | if (updateCount != -1) { |
1051 | 0 | updateCountTotal += updateCount; |
1052 | } | |
1053 | 0 | } else { |
1054 | 0 | resultSet = statement.getResultSet(); |
1055 | 0 | if (printResultSet) { |
1056 | 0 | printResultSet(resultSet, out); |
1057 | } | |
1058 | } | |
1059 | 0 | ret = statement.getMoreResults(); |
1060 | 0 | } while (ret); |
1061 | ||
1062 | 0 | getLog().debug(updateCountTotal + " rows affected"); |
1063 | ||
1064 | 0 | if (printResultSet) { |
1065 | 0 | StringBuffer line = new StringBuffer(); |
1066 | 0 | line.append(updateCountTotal).append(" rows affected"); |
1067 | 0 | out.println(line); |
1068 | } | |
1069 | ||
1070 | 0 | SQLWarning warning = conn.getWarnings(); |
1071 | 0 | while (warning != null) { |
1072 | 0 | getLog().debug(warning + " sql warning"); |
1073 | 0 | warning = warning.getNextWarning(); |
1074 | } | |
1075 | 0 | conn.clearWarnings(); |
1076 | 0 | successfulStatements++; |
1077 | 0 | } catch (SQLException e) { |
1078 | 0 | getLog().error("Failed to execute: " + sql); |
1079 | 0 | if (ON_ERROR_ABORT.equalsIgnoreCase(getOnError())) { |
1080 | 0 | throw e; |
1081 | } | |
1082 | 0 | getLog().error(e.toString()); |
1083 | } finally { | |
1084 | 0 | if (resultSet != null) { |
1085 | 0 | resultSet.close(); |
1086 | } | |
1087 | } | |
1088 | 0 | } |
1089 | ||
1090 | /** | |
1091 | * print any results in the result set. | |
1092 | * | |
1093 | * @param rs | |
1094 | * the resultset to print information about | |
1095 | * @param out | |
1096 | * the place to print results | |
1097 | * @throws SQLException | |
1098 | * on SQL problems. | |
1099 | */ | |
1100 | private void printResultSet(ResultSet rs, PrintStream out) throws SQLException { | |
1101 | 0 | if (rs != null) { |
1102 | 0 | getLog().debug("Processing new result set."); |
1103 | 0 | ResultSetMetaData md = rs.getMetaData(); |
1104 | 0 | int columnCount = md.getColumnCount(); |
1105 | 0 | StringBuffer line = new StringBuffer(); |
1106 | 0 | if (showheaders) { |
1107 | 0 | boolean first = true; |
1108 | 0 | for (int col = 1; col <= columnCount; col++) { |
1109 | 0 | String columnValue = md.getColumnName(col); |
1110 | ||
1111 | 0 | if (columnValue != null) { |
1112 | 0 | columnValue = columnValue.trim(); |
1113 | ||
1114 | 0 | if (",".equals(outputDelimiter)) { |
1115 | 0 | columnValue = StringEscapeUtils.escapeCsv(columnValue); |
1116 | } | |
1117 | } | |
1118 | ||
1119 | 0 | if (first) { |
1120 | 0 | first = false; |
1121 | } else { | |
1122 | 0 | line.append(outputDelimiter); |
1123 | } | |
1124 | 0 | line.append(columnValue); |
1125 | } | |
1126 | 0 | out.println(line); |
1127 | 0 | line = new StringBuffer(); |
1128 | } | |
1129 | 0 | while (rs.next()) { |
1130 | 0 | boolean first = true; |
1131 | 0 | for (int col = 1; col <= columnCount; col++) { |
1132 | 0 | String columnValue = rs.getString(col); |
1133 | 0 | if (columnValue != null) { |
1134 | 0 | columnValue = columnValue.trim(); |
1135 | ||
1136 | 0 | if (",".equals(outputDelimiter)) { |
1137 | 0 | columnValue = StringEscapeUtils.escapeCsv(columnValue); |
1138 | } | |
1139 | } | |
1140 | ||
1141 | 0 | if (first) { |
1142 | 0 | first = false; |
1143 | } else { | |
1144 | 0 | line.append(outputDelimiter); |
1145 | } | |
1146 | 0 | line.append(columnValue); |
1147 | } | |
1148 | 0 | out.println(line); |
1149 | 0 | line = new StringBuffer(); |
1150 | 0 | } |
1151 | } | |
1152 | 0 | out.println(); |
1153 | 0 | } |
1154 | ||
1155 | /** | |
1156 | * Contains the definition of a new transaction element. Transactions allow | |
1157 | * several files or blocks of statements to be executed using the same JDBC | |
1158 | * connection and commit operation in between. | |
1159 | */ | |
1160 | 0 | private class Transaction implements Comparable<Transaction> { |
1161 | 0 | private File tSrcFile = null; |
1162 | ||
1163 | 0 | private String tSqlCommand = ""; |
1164 | ||
1165 | /** | |
1166 | * | |
1167 | */ | |
1168 | public void setSrc(File src) { | |
1169 | 0 | this.tSrcFile = src; |
1170 | 0 | } |
1171 | ||
1172 | /** | |
1173 | * | |
1174 | */ | |
1175 | public void addText(String sql) { | |
1176 | 0 | this.tSqlCommand += sql; |
1177 | 0 | } |
1178 | ||
1179 | /** | |
1180 | * | |
1181 | */ | |
1182 | private void runTransaction(PrintStream out) throws IOException, SQLException { | |
1183 | 0 | if (tSqlCommand.length() != 0) { |
1184 | 0 | getLog().info("Executing commands"); |
1185 | ||
1186 | 0 | runStatements(new StringReader(tSqlCommand), out); |
1187 | } | |
1188 | ||
1189 | 0 | if (tSrcFile != null) { |
1190 | 0 | getLog().info("Executing file: " + tSrcFile.getAbsolutePath()); |
1191 | ||
1192 | 0 | Reader reader = null; |
1193 | ||
1194 | 0 | if (StringUtils.isEmpty(encoding)) { |
1195 | 0 | reader = new FileReader(tSrcFile); |
1196 | } else { | |
1197 | 0 | reader = new InputStreamReader(new FileInputStream(tSrcFile), encoding); |
1198 | } | |
1199 | ||
1200 | try { | |
1201 | 0 | runStatements(reader, out); |
1202 | } finally { | |
1203 | 0 | reader.close(); |
1204 | 0 | } |
1205 | } | |
1206 | 0 | } |
1207 | ||
1208 | public int compareTo(Transaction transaction) { | |
1209 | ||
1210 | 0 | if (transaction.tSrcFile == null) { |
1211 | 0 | if (this.tSrcFile == null) { |
1212 | 0 | return 0; |
1213 | } else { | |
1214 | 0 | return Integer.MAX_VALUE; |
1215 | } | |
1216 | } else { | |
1217 | 0 | if (this.tSrcFile == null) { |
1218 | 0 | return Integer.MIN_VALUE; |
1219 | } else { | |
1220 | 0 | return this.tSrcFile.compareTo(transaction.tSrcFile); |
1221 | } | |
1222 | } | |
1223 | } | |
1224 | } | |
1225 | ||
1226 | // | |
1227 | // helper accessors for unit test purposes | |
1228 | // | |
1229 | ||
1230 | public String getUsername() { | |
1231 | 0 | return this.username; |
1232 | } | |
1233 | ||
1234 | public void setUsername(String username) { | |
1235 | 0 | this.username = username; |
1236 | 0 | } |
1237 | ||
1238 | public String getPassword() { | |
1239 | 0 | return this.password; |
1240 | } | |
1241 | ||
1242 | public void setPassword(String password) { | |
1243 | 0 | this.password = password; |
1244 | 0 | } |
1245 | ||
1246 | public String getUrl() { | |
1247 | 0 | return this.url; |
1248 | } | |
1249 | ||
1250 | public void setUrl(String url) { | |
1251 | 0 | this.url = url; |
1252 | 0 | } |
1253 | ||
1254 | public String getDriver() { | |
1255 | 0 | return this.driver; |
1256 | } | |
1257 | ||
1258 | public void setDriver(String driver) { | |
1259 | 0 | this.driver = driver; |
1260 | 0 | } |
1261 | ||
1262 | void setAutocommit(boolean autocommit) { | |
1263 | 0 | this.autocommit = autocommit; |
1264 | 0 | } |
1265 | ||
1266 | void setFileset(Fileset fileset) { | |
1267 | 0 | this.fileset = fileset; |
1268 | 0 | } |
1269 | ||
1270 | public File[] getSrcFiles() { | |
1271 | 0 | return this.srcFiles; |
1272 | } | |
1273 | ||
1274 | public void setSrcFiles(File[] files) { | |
1275 | 0 | this.srcFiles = files; |
1276 | 0 | } |
1277 | ||
1278 | public String getOrderFile() { | |
1279 | 0 | return this.orderFile; |
1280 | } | |
1281 | ||
1282 | public void setOrderFile(String orderFile) { | |
1283 | 0 | if (FILE_SORTING_ASC.equalsIgnoreCase(orderFile)) { |
1284 | 0 | this.orderFile = FILE_SORTING_ASC; |
1285 | 0 | } else if (FILE_SORTING_DSC.equalsIgnoreCase(orderFile)) { |
1286 | 0 | this.orderFile = FILE_SORTING_DSC; |
1287 | } else { | |
1288 | 0 | throw new IllegalArgumentException(orderFile + " is not a valid value for orderFile, only '" |
1289 | + FILE_SORTING_ASC + "' or '" + FILE_SORTING_DSC + "'."); | |
1290 | } | |
1291 | 0 | } |
1292 | ||
1293 | /** | |
1294 | * @deprecated use {@link #getSuccessfulStatements()} | |
1295 | */ | |
1296 | int getGoodSqls() { | |
1297 | 0 | return this.getSuccessfulStatements(); |
1298 | } | |
1299 | ||
1300 | /** | |
1301 | * Number of SQL statements executed so far that caused errors. | |
1302 | * | |
1303 | * @return the number | |
1304 | */ | |
1305 | public int getSuccessfulStatements() { | |
1306 | 0 | return successfulStatements; |
1307 | } | |
1308 | ||
1309 | /** | |
1310 | * Number of SQL statements executed so far, including the ones that caused | |
1311 | * errors. | |
1312 | * | |
1313 | * @return the number | |
1314 | */ | |
1315 | public int getTotalStatements() { | |
1316 | 0 | return totalStatements; |
1317 | } | |
1318 | ||
1319 | public String getOnError() { | |
1320 | 0 | return this.onError; |
1321 | } | |
1322 | ||
1323 | public void setOnError(String action) { | |
1324 | 0 | if (ON_ERROR_ABORT.equalsIgnoreCase(action)) { |
1325 | 0 | this.onError = ON_ERROR_ABORT; |
1326 | 0 | } else if (ON_ERROR_CONTINUE.equalsIgnoreCase(action)) { |
1327 | 0 | this.onError = ON_ERROR_CONTINUE; |
1328 | 0 | } else if (ON_ERROR_ABORT_AFTER.equalsIgnoreCase(action)) { |
1329 | 0 | this.onError = ON_ERROR_ABORT_AFTER; |
1330 | } else { | |
1331 | 0 | throw new IllegalArgumentException(action + " is not a valid value for onError, only '" + ON_ERROR_ABORT |
1332 | + "', '" + ON_ERROR_ABORT_AFTER + "', or '" + ON_ERROR_CONTINUE + "'."); | |
1333 | } | |
1334 | 0 | } |
1335 | ||
1336 | void setSettings(Settings settings) { | |
1337 | 0 | this.settings = settings; |
1338 | 0 | } |
1339 | ||
1340 | void setSettingsKey(String key) { | |
1341 | 0 | this.settingsKey = key; |
1342 | 0 | } |
1343 | ||
1344 | void setSkip(boolean skip) { | |
1345 | 0 | this.skip = skip; |
1346 | 0 | } |
1347 | ||
1348 | public void setDriverProperties(String driverProperties) { | |
1349 | 0 | this.driverProperties = driverProperties; |
1350 | 0 | } |
1351 | ||
1352 | public boolean isEnableBlockMode() { | |
1353 | 0 | return enableBlockMode; |
1354 | } | |
1355 | ||
1356 | public void setEnableBlockMode(boolean enableBlockMode) { | |
1357 | 0 | this.enableBlockMode = enableBlockMode; |
1358 | 0 | } |
1359 | ||
1360 | public String getSqlCommand() { | |
1361 | 0 | return sqlCommand; |
1362 | } | |
1363 | ||
1364 | public void setSqlCommand(String sqlCommand) { | |
1365 | 0 | this.sqlCommand = sqlCommand; |
1366 | 0 | } |
1367 | ||
1368 | public Vector<Transaction> getTransactions() { | |
1369 | 0 | return transactions; |
1370 | } | |
1371 | ||
1372 | public void setTransactions(Vector<Transaction> transactions) { | |
1373 | 0 | this.transactions = transactions; |
1374 | 0 | } |
1375 | ||
1376 | public void setFileFilter(MavenFileFilter filter) { | |
1377 | 0 | this.fileFilter = filter; |
1378 | 0 | } |
1379 | ||
1380 | public String[] getResourceLocations() { | |
1381 | 0 | return resourceLocations; |
1382 | } | |
1383 | ||
1384 | public void setResourceLocations(String[] resourceLocations) { | |
1385 | 0 | this.resourceLocations = resourceLocations; |
1386 | 0 | } |
1387 | } |