1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.codehaus.mojo.sql;
17  
18  import java.io.BufferedOutputStream;
19  import java.io.BufferedReader;
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.FileOutputStream;
23  import java.io.FileReader;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.OutputStream;
28  import java.io.PrintStream;
29  import java.io.Reader;
30  import java.io.StringReader;
31  import java.net.URL;
32  import java.sql.Connection;
33  import java.sql.Driver;
34  import java.sql.ResultSet;
35  import java.sql.ResultSetMetaData;
36  import java.sql.SQLException;
37  import java.sql.SQLWarning;
38  import java.sql.Statement;
39  import java.util.ArrayList;
40  import java.util.Collections;
41  import java.util.Enumeration;
42  import java.util.List;
43  import java.util.Properties;
44  import java.util.StringTokenizer;
45  import java.util.Vector;
46  
47  import org.apache.commons.io.IOUtils;
48  import org.apache.commons.lang.StringEscapeUtils;
49  import org.apache.commons.lang.StringUtils;
50  import org.apache.maven.execution.MavenSession;
51  import org.apache.maven.plugin.AbstractMojo;
52  import org.apache.maven.plugin.MojoExecutionException;
53  import org.apache.maven.project.MavenProject;
54  import org.apache.maven.settings.Server;
55  import org.apache.maven.settings.Settings;
56  import org.apache.maven.shared.filtering.MavenFileFilter;
57  import org.apache.maven.shared.filtering.MavenFileFilterRequest;
58  import org.apache.maven.shared.filtering.MavenFilteringException;
59  import org.codehaus.plexus.util.FileUtils;
60  import org.springframework.core.io.DefaultResourceLoader;
61  import org.springframework.core.io.Resource;
62  import org.springframework.core.io.ResourceLoader;
63  
64  
65  
66  
67  
68  
69  public class SqlExecMojo extends AbstractMojo {
70  
71  	
72  
73  
74  	public static final String ON_ERROR_ABORT = "abort";
75  
76  	
77  
78  
79  
80  	public static final String ON_ERROR_ABORT_AFTER = "abortAfter";
81  
82  	
83  
84  
85  	public static final String ON_ERROR_CONTINUE = "continue";
86  
87  	
88  
89  	
90  
91  
92  
93  
94  	private boolean showSql;
95  
96  	
97  
98  
99  
100 
101 
102 
103 	private String username;
104 
105 	
106 
107 
108 
109 
110 
111 
112 	private String password;
113 
114 	
115 
116 
117 
118 
119 
120 
121 
122 
123 	private boolean enableAnonymousPassword;
124 
125 	
126 
127 
128 
129 
130 
131 	private String driverProperties;
132 
133 	
134 
135 
136 
137 
138 
139 	private Settings settings;
140 
141 	
142 
143 
144 
145 
146 
147 	private String settingsKey;
148 
149 	
150 
151 
152 
153 
154 
155 
156 	private boolean skipOnConnectionError;
157 
158 	
159 
160 
161 
162 
163 
164 	private boolean forceMojoExecution;
165 
166 	
167 
168 
169 
170 
171 
172 
173 	protected MavenProject project;
174 
175 	
176 
177 
178 
179 
180 	private MavenSession mavenSession;
181 
182 	
183 
184 	
185 
186 
187 
188 
189 
190 	private String sqlCommand = "";
191 
192 	
193 
194 
195 
196 
197 
198 	private File[] srcFiles;
199 
200 	
201 
202 
203 
204 
205 	private String resourceListingLocation;
206 
207 	
208 
209 
210 
211 
212 
213 	private String[] resourceLocations;
214 
215 	
216 
217 
218 
219 
220 
221 	private Fileset fileset;
222 
223 	
224 
225 
226 
227 
228 
229 	private boolean skip;
230 
231 	
232 	
233 
234 
235 
236 
237 
238 
239 	private String url;
240 
241 	
242 
243 
244 
245 
246 
247 
248 	private String driver;
249 
250 	
251 	
252 
253 
254 
255 
256 
257 	private boolean autocommit;
258 
259 	
260 
261 
262 
263 
264 
265 	private String onError = ON_ERROR_ABORT;
266 
267 	
268 
269 	
270 
271 
272 
273 
274 
275 	private String delimiter = ";";
276 
277 	
278 
279 
280 
281 
282 
283 
284 
285 
286 
287 
288 
289 	private String delimiterType = DelimiterType.NORMAL;
290 
291 	
292 
293 
294 
295 
296 
297 
298 	private Order orderFile;
299 
300 	
301 
302 
303 
304 
305 
306 
307 
308 
309 	@Deprecated
310 	private boolean enableBlockMode = false;
311 
312 	
313 
314 
315 
316 
317 
318 	private boolean keepFormat = false;
319 
320 	
321 	
322 
323 
324 
325 
326 
327 	private boolean printResultSet = false;
328 
329 	
330 
331 
332 	private boolean showheaders = true;
333 
334 	
335 
336 
337 
338 
339 
340 	private File outputFile;
341 
342 	
343 
344 
345 
346 	private String outputDelimiter;
347 
348 	
349 
350 
351 
352 
353 
354 	private String encoding = "";
355 
356 	
357 
358 
359 	private boolean append = false;
360 
361 	
362 
363 
364 
365 
366 
367 	private boolean escapeProcessing = true;
368 
369 	
370 	
371 
372 	
373 
374 
375 	private int successfulStatements = 0;
376 
377 	
378 
379 
380 	private int totalStatements = 0;
381 
382 	
383 
384 
385 	private Connection conn = null;
386 
387 	
388 
389 
390 	private Statement statement = null;
391 
392 	
393 
394 
395 	protected Vector<Transaction> transactions = new Vector<Transaction>();
396 
397 	
398 
399 
400 
401 	private MavenFileFilter fileFilter;
402 
403 	
404 
405 
406 
407 
408 
409 	private boolean enableFiltering;
410 
411 	
412 
413 
414 
415 
416 
417 
418 	private boolean executeTrailingSQL;
419 
420 	
421 
422 
423 	
424 	
425 
426 	
427 
428 
429 
430 
431 	public Transaction createTransaction() {
432 		Transaction t = new Transaction();
433 		transactions.addElement(t);
434 		return t;
435 	}
436 
437 	
438 
439 
440 
441 
442 
443 	public void addText(String sql) {
444 		this.sqlCommand += sql;
445 	}
446 
447 	
448 
449 
450 
451 
452 
453 	public void setEncoding(String encoding) {
454 		this.encoding = encoding;
455 	}
456 
457 	
458 
459 
460 
461 
462 
463 	public void setDelimiter(String delimiter) {
464 		this.delimiter = delimiter;
465 	}
466 
467 	
468 
469 
470 
471 
472 
473 	public void setDelimiterType(String delimiterType) {
474 		this.delimiterType = delimiterType;
475 	}
476 
477 	
478 
479 
480 
481 
482 
483 
484 	@Deprecated
485 	public void setPrintResutlSet(boolean print) {
486 		setPrintResultSet(print);
487 	}
488 
489 	
490 
491 
492 
493 
494 
495 	public void setPrintResultSet(boolean print) {
496 		this.printResultSet = print;
497 	}
498 
499 	
500 
501 
502 
503 
504 
505 	public void setShowheaders(boolean showheaders) {
506 		this.showheaders = showheaders;
507 	}
508 
509 	
510 
511 
512 
513 
514 
515 	public void setOutputFile(File output) {
516 		this.outputFile = output;
517 	}
518 
519 	
520 
521 
522 
523 
524 
525 	public void setAppend(boolean append) {
526 		this.append = append;
527 	}
528 
529 	
530 
531 
532 
533 
534 
535 	public void setKeepFormat(boolean keepformat) {
536 		this.keepFormat = keepformat;
537 	}
538 
539 	
540 
541 
542 
543 
544 
545 	public void setEscapeProcessing(boolean enable) {
546 		escapeProcessing = enable;
547 	}
548 
549 	
550 
551 
552 
553 
554 
555 
556 
557 
558 
559 
560 
561 	protected boolean skipMojo() {
562 		if (skip) {
563 			getLog().info("Skip sql execution");
564 			return true;
565 		}
566 
567 		if (!forceMojoExecution && project != null && "pom".equals(project.getPackaging())) {
568 			getLog().info("Skipping sql execution for project with packaging type 'pom'");
569 			return true;
570 		}
571 
572 		return false;
573 	}
574 
575 	
576 
577 
578 
579 
580 	@Override
581 	public void execute() throws MojoExecutionException {
582 
583 		if (skipMojo()) {
584 			return;
585 		}
586 
587 		successfulStatements = 0;
588 
589 		totalStatements = 0;
590 
591 		loadUserInfoFromSettings();
592 
593 		addCommandToTransactions();
594 
595 		addFilesToTransactions();
596 
597 		addFileSetToTransactions();
598 
599 		addResourcesToTransactions();
600 
601 		sortTransactions();
602 
603 		try {
604 			conn = getConnection();
605 		} catch (SQLException e) {
606 			if (!this.skipOnConnectionError) {
607 				throw new MojoExecutionException(e.getMessage(), e);
608 			} else {
609 				
610 				return;
611 			}
612 		}
613 
614 		try {
615 			statement = conn.createStatement();
616 			statement.setEscapeProcessing(escapeProcessing);
617 
618 			PrintStream out = System.out;
619 			try {
620 				if (outputFile != null) {
621 					getLog().debug("Opening PrintStream to output file " + outputFile);
622 					out = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile.getAbsolutePath(), append)));
623 				}
624 
625 				
626 				for (Enumeration<Transaction> e = transactions.elements(); e.hasMoreElements();) {
627 					Transaction t = e.nextElement();
628 
629 					t.runTransaction(out);
630 
631 					if (!autocommit) {
632 						getLog().debug("Committing transaction");
633 						conn.commit();
634 					}
635 				}
636 			} finally {
637 				if (out != null && out != System.out) {
638 					out.close();
639 				}
640 			}
641 		} catch (IOException e) {
642 			throw new MojoExecutionException(e.getMessage(), e);
643 		} catch (SQLException e) {
644 			if (!autocommit && conn != null && ON_ERROR_ABORT.equalsIgnoreCase(getOnError())) {
645 				try {
646 					conn.rollback();
647 				} catch (SQLException ex) {
648 					
649 				}
650 			}
651 			throw new MojoExecutionException(e.getMessage(), e);
652 		} finally {
653 			try {
654 				if (statement != null) {
655 					statement.close();
656 				}
657 				if (conn != null) {
658 					conn.close();
659 				}
660 			} catch (SQLException ex) {
661 				
662 			}
663 		}
664 
665 		getLog().info(getSuccessfulStatements() + " of " + getTotalStatements() + " SQL statements executed successfully");
666 
667 		if (ON_ERROR_ABORT_AFTER.equalsIgnoreCase(getOnError()) && totalStatements != successfulStatements) {
668 			throw new MojoExecutionException("Some SQL statements failed to execute");
669 		}
670 
671 	}
672 
673 	
674 
675 
676 
677 	private void addCommandToTransactions() {
678 		createTransaction().addText(sqlCommand.trim());
679 	}
680 
681 	
682 
683 
684 
685 	private void addFileSetToTransactions() {
686 		String[] includedFiles;
687 		if (fileset != null) {
688 			fileset.scan();
689 			includedFiles = fileset.getIncludedFiles();
690 		} else {
691 			includedFiles = new String[0];
692 		}
693 
694 		for (int j = 0; j < includedFiles.length; j++) {
695 			createTransaction().setSrc(new File(fileset.getBasedir(), includedFiles[j]));
696 		}
697 	}
698 
699 	protected SqlResource[] getResources(String[] locations, String resourceListingLocation) throws MojoExecutionException {
700 		ResourceLoader loader = new DefaultResourceLoader();
701 		if (StringUtils.isBlank(resourceListingLocation)) {
702 			return getResources(locations);
703 		}
704 		Resource resource = loader.getResource(resourceListingLocation);
705 		if (!resource.exists()) {
706 			throw new MojoExecutionException("Resource [" + resourceListingLocation + "] was not found");
707 		}
708 		getLog().info("Examining [" + getURL(resource) + "]");
709 		List<String> locs = readLines(resource);
710 		if (locations == null) {
711 			locs = trim(locs);
712 			getLog().info("Found " + locs.size() + " locations");
713 			return getResources(locs.toArray(new String[locs.size()]));
714 		}
715 		for (String location : locations) {
716 			locs.add(location);
717 		}
718 		locs = trim(locs);
719 		return getResources(locs.toArray(new String[locs.size()]));
720 	}
721 
722 	protected URL getURL(Resource resource) {
723 		try {
724 			return resource.getURL();
725 		} catch (IOException e) {
726 			throw new IllegalArgumentException("Unexpected IO error", e);
727 		}
728 	}
729 
730 	protected List<String> trim(List<String> lines) {
731 		List<String> trimmed = new ArrayList<String>();
732 		for (String line : lines) {
733 			trimmed.add(StringUtils.trim(line));
734 		}
735 		return trimmed;
736 	}
737 
738 	protected List<String> readLines(Resource resource) {
739 		InputStream in = null;
740 		try {
741 			in = resource.getInputStream();
742 			if (StringUtils.isBlank(encoding)) {
743 				return IOUtils.readLines(in);
744 			} else {
745 				return IOUtils.readLines(in, encoding);
746 			}
747 		} catch (IOException e) {
748 			throw new IllegalStateException("Unexpected IO error", e);
749 		} finally {
750 			IOUtils.closeQuietly(in);
751 		}
752 	}
753 
754 	protected SqlResource[] getResources(String[] locations) throws MojoExecutionException {
755 		ResourceLoader loader = new DefaultResourceLoader();
756 		if (locations == null || locations.length == 0) {
757 			return new SqlResource[] {};
758 		}
759 		List<SqlResource> resources = new ArrayList<SqlResource>();
760 		for (int i = 0; i < locations.length; i++) {
761 			String location = locations[i];
762 			
763 			if (StringUtils.isEmpty(location)) {
764 				continue;
765 			}
766 			Resource resource = loader.getResource(location);
767 			if (!resource.exists()) {
768 				
769 				throw new MojoExecutionException("Resource " + location + " was not found");
770 			}
771 			SqlResource sqlResource = new SqlResource();
772 			sqlResource.setLocation(location);
773 			sqlResource.setResource(resource);
774 			resources.add(sqlResource);
775 		}
776 		return resources.toArray(new SqlResource[resources.size()]);
777 	}
778 
779 	protected void copy(Resource resource, File file) throws IOException {
780 		InputStream in = null;
781 		OutputStream out = null;
782 		try {
783 			in = resource.getInputStream();
784 			out = new FileOutputStream(file);
785 			IOUtils.copyLarge(in, out);
786 		} finally {
787 			IOUtils.closeQuietly(in);
788 			IOUtils.closeQuietly(out);
789 		}
790 	}
791 
792 	
793 
794 
795 
796 
797 	protected void addResourcesToTransactions() throws MojoExecutionException {
798 		String[] locations = getResourceLocations();
799 		SqlResource[] resources = getResources(locations, resourceListingLocation);
800 
801 		MavenFileFilterRequest request = new MavenFileFilterRequest();
802 		request.setEncoding(encoding);
803 		request.setMavenSession(mavenSession);
804 		request.setMavenProject(project);
805 		request.setFiltering(enableFiltering);
806 		for (int i = 0; i < resources.length; i++) {
807 			SqlResource resource = resources[i];
808 
809 			if (!enableFiltering) {
810 				createTransaction().setResource(resource);
811 				continue;
812 			}
813 
814 			String filename = resource.getResource().getFilename();
815 			String basename = FileUtils.basename(filename);
816 			String extension = FileUtils.extension(filename);
817 			if (!extension.startsWith(".")) {
818 				extension = "." + extension;
819 			}
820 			File sourceFile = FileUtils.createTempFile(basename, extension, null);
821 			if (!getLog().isDebugEnabled()) {
822 				sourceFile.deleteOnExit();
823 			}
824 
825 			try {
826 				copy(resource.getResource(), sourceFile);
827 			} catch (IOException e) {
828 				throw new MojoExecutionException("Error copying resource " + resource.getResource() + " to a local temporary file", e);
829 			}
830 
831 			if (!enableFiltering) {
832 				createTransaction().setSrc(sourceFile);
833 				continue;
834 			}
835 
836 			File targetFile = FileUtils.createTempFile(basename, extension, null);
837 			if (!getLog().isDebugEnabled()) {
838 				sourceFile.deleteOnExit();
839 			}
840 
841 			request.setFrom(sourceFile);
842 			request.setTo(targetFile);
843 
844 			try {
845 				fileFilter.copyFile(request);
846 			} catch (MavenFilteringException e) {
847 				throw new MojoExecutionException(e.getMessage());
848 			}
849 
850 			createTransaction().setSrc(targetFile);
851 		}
852 	}
853 
854 	
855 
856 
857 
858 
859 	private void addFilesToTransactions() throws MojoExecutionException {
860 		File[] files = getSrcFiles();
861 
862 		MavenFileFilterRequest request = new MavenFileFilterRequest();
863 		request.setEncoding(encoding);
864 		request.setMavenSession(mavenSession);
865 		request.setMavenProject(project);
866 		request.setFiltering(enableFiltering);
867 		for (int i = 0; files != null && i < files.length; ++i) {
868 			if (files[i] != null && !files[i].exists()) {
869 				throw new MojoExecutionException(files[i].getPath() + " not found.");
870 			}
871 
872 			if (!enableFiltering) {
873 				createTransaction().setSrc(files[i]);
874 				continue;
875 			}
876 
877 			File sourceFile = files[i];
878 			String basename = FileUtils.basename(sourceFile.getName());
879 			String extension = FileUtils.extension(sourceFile.getName());
880 			if (!extension.startsWith(".")) {
881 				extension = "." + extension;
882 			}
883 			File targetFile = FileUtils.createTempFile(basename, extension, null);
884 			if (!getLog().isDebugEnabled()) {
885 				targetFile.deleteOnExit();
886 			}
887 
888 			request.setFrom(sourceFile);
889 			request.setTo(targetFile);
890 
891 			try {
892 				fileFilter.copyFile(request);
893 			} catch (MavenFilteringException e) {
894 				throw new MojoExecutionException(e.getMessage());
895 			}
896 
897 			createTransaction().setSrc(targetFile);
898 		}
899 	}
900 
901 	
902 
903 
904 	protected void sortTransactions() {
905 		switch (orderFile) {
906 		case ASCENDING:
907 			Collections.sort(transactions);
908 			break;
909 		case DESCENDING:
910 			Collections.sort(transactions, Collections.reverseOrder());
911 			break;
912 		case NONE:
913 			break;
914 		default:
915 			throw new RuntimeException("Unknown value for orderFile: " + orderFile);
916 		}
917 	}
918 
919 	
920 
921 
922 
923 
924 	private void loadUserInfoFromSettings() throws MojoExecutionException {
925 		if (this.settingsKey == null) {
926 			this.settingsKey = getUrl();
927 		}
928 
929 		if ((getUsername() == null || getPassword() == null) && (settings != null)) {
930 			Server server = this.settings.getServer(this.settingsKey);
931 
932 			if (server != null) {
933 				if (getUsername() == null) {
934 					setUsername(server.getUsername());
935 				}
936 
937 				if (getPassword() == null) {
938 					setPassword(server.getPassword());
939 				}
940 			}
941 		}
942 
943 		if (getUsername() == null) {
944 			
945 			setUsername("");
946 		}
947 
948 		if (getPassword() == null) {
949 			
950 			setPassword("");
951 		}
952 	}
953 
954 	
955 
956 
957 
958 
959 
960 
961 
962 
963 
964 
965 
966 	private Connection getConnection() throws MojoExecutionException, SQLException {
967 		getLog().debug("connecting to " + getUrl());
968 
969 		Properties properties = getProperties();
970 		Connection conn = getDriverInstance().connect(getUrl(), properties);
971 
972 		if (conn == null) {
973 			
974 			throw new SQLException("No suitable Driver for " + getUrl());
975 		}
976 
977 		conn.setAutoCommit(autocommit);
978 		return conn;
979 	}
980 
981 	protected boolean isBlankOrNone(String s) {
982 		return StringUtils.isBlank(s) || "NONE".equals(s.trim());
983 	}
984 
985 	protected boolean isSkipPassword() {
986 		return enableAnonymousPassword && isBlankOrNone(getPassword());
987 	}
988 
989 	protected Properties getProperties() throws MojoExecutionException {
990 		Properties properties = new Properties();
991 		properties.put("user", getUsername());
992 
993 		if (!isSkipPassword()) {
994 			properties.put("password", getPassword());
995 		}
996 		properties.putAll(this.getDriverProperties());
997 		return properties;
998 	}
999 
1000 	protected Driver getDriverInstance() throws MojoExecutionException {
1001 		try {
1002 			Class<?> dc = Class.forName(getDriver());
1003 			return (Driver) dc.newInstance();
1004 		} catch (ClassNotFoundException e) {
1005 			throw new MojoExecutionException("Driver class not found: " + getDriver(), e);
1006 		} catch (Exception e) {
1007 			throw new MojoExecutionException("Failure loading driver: " + getDriver(), e);
1008 		}
1009 	}
1010 
1011 	
1012 
1013 
1014 
1015 
1016 
1017 	protected Properties getDriverProperties() throws MojoExecutionException {
1018 		Properties properties = new Properties();
1019 
1020 		if (!StringUtils.isEmpty(this.driverProperties)) {
1021 			String[] tokens = StringUtils.split(this.driverProperties, ",");
1022 			for (int i = 0; i < tokens.length; ++i) {
1023 				String[] keyValueTokens = StringUtils.split(tokens[i].trim(), "=");
1024 				if (keyValueTokens.length != 2) {
1025 					throw new MojoExecutionException("Invalid JDBC Driver properties: " + this.driverProperties);
1026 				}
1027 
1028 				properties.setProperty(keyValueTokens[0], keyValueTokens[1]);
1029 
1030 			}
1031 		}
1032 
1033 		return properties;
1034 	}
1035 
1036 	
1037 
1038 
1039 
1040 
1041 
1042 
1043 
1044 
1045 
1046 	private void runStatements(Reader reader, PrintStream out) throws SQLException, IOException {
1047 		String line;
1048 
1049 		if (enableBlockMode) {
1050 			
1051 			
1052 			line = IOUtils.toString(reader);
1053 			execSQL(line, out);
1054 			return;
1055 		}
1056 
1057 		StringBuffer sql = new StringBuffer();
1058 
1059 		BufferedReader in = new BufferedReader(reader);
1060 
1061 		while ((line = in.readLine()) != null) {
1062 			getLog().debug("line='" + line + "'");
1063 			if (!keepFormat) {
1064 				line = line.trim();
1065 			}
1066 
1067 			if (!keepFormat) {
1068 				if (line.startsWith("//")) {
1069 					continue;
1070 				}
1071 				if (line.startsWith("--")) {
1072 					continue;
1073 				}
1074 				StringTokenizer st = new StringTokenizer(line);
1075 				if (st.hasMoreTokens()) {
1076 					String token = st.nextToken();
1077 					if ("REM".equalsIgnoreCase(token)) {
1078 						continue;
1079 					}
1080 				}
1081 			}
1082 
1083 			if (!keepFormat) {
1084 				sql.append(" ").append(line);
1085 			} else {
1086 				sql.append("\n").append(line);
1087 			}
1088 
1089 			
1090 			
1091 			
1092 			if (!keepFormat) {
1093 				if (SqlSplitter.containsSqlEnd(line, delimiter) == SqlSplitter.NO_END) {
1094 					sql.append("\n");
1095 				}
1096 			}
1097 
1098 			if (isEnd(line)) {
1099 				execSQL(sql.substring(0, sql.length() - delimiter.length()), out);
1100 				sql.setLength(0); 
1101 			}
1102 		}
1103 
1104 		
1105 		if (executeTrailingSQL && !sql.toString().equals("")) {
1106 			execSQL(sql.toString(), out);
1107 		}
1108 	}
1109 
1110 	protected boolean isEnd(String line) {
1111 		if (delimiterType.equals(DelimiterType.ROW)) {
1112 			return line.trim().equals(delimiter);
1113 		}
1114 		int pos = SqlSplitter.containsSqlEnd(line, delimiter);
1115 		if (delimiterType.equals(DelimiterType.NORMAL) && pos > 0) {
1116 			return true;
1117 		}
1118 		return false;
1119 	}
1120 
1121 	
1122 
1123 
1124 
1125 
1126 
1127 
1128 
1129 	private void execSQL(String sql, PrintStream out) throws SQLException {
1130 		
1131 		if ("".equals(sql.trim())) {
1132 			return;
1133 		}
1134 
1135 		ResultSet resultSet = null;
1136 		try {
1137 			totalStatements++;
1138 			if (showSql) {
1139 				getLog().info("SQL-" + totalStatements + ": " + sql);
1140 			} else {
1141 				getLog().debug("SQL-" + totalStatements + ": " + sql);
1142 			}
1143 
1144 			boolean ret;
1145 			int updateCountTotal = 0;
1146 
1147 			ret = statement.execute(sql);
1148 			do {
1149 				if (!ret) {
1150 					int updateCount = statement.getUpdateCount();
1151 					if (updateCount != -1) {
1152 						updateCountTotal += updateCount;
1153 					}
1154 				} else {
1155 					resultSet = statement.getResultSet();
1156 					if (printResultSet) {
1157 						printResultSet(resultSet, out);
1158 					}
1159 				}
1160 				ret = statement.getMoreResults();
1161 			} while (ret);
1162 
1163 			getLog().debug(updateCountTotal + " rows affected");
1164 
1165 			if (printResultSet) {
1166 				StringBuffer line = new StringBuffer();
1167 				line.append(updateCountTotal).append(" rows affected");
1168 				out.println(line);
1169 			}
1170 
1171 			SQLWarning warning = conn.getWarnings();
1172 			while (warning != null) {
1173 				getLog().debug(warning + " sql warning");
1174 				warning = warning.getNextWarning();
1175 			}
1176 			conn.clearWarnings();
1177 			successfulStatements++;
1178 		} catch (SQLException e) {
1179 			getLog().error("Failed to execute: " + sql);
1180 			if (ON_ERROR_ABORT.equalsIgnoreCase(getOnError())) {
1181 				throw e;
1182 			}
1183 			getLog().error(e.toString());
1184 		} finally {
1185 			if (resultSet != null) {
1186 				resultSet.close();
1187 			}
1188 		}
1189 	}
1190 
1191 	
1192 
1193 
1194 
1195 
1196 
1197 
1198 
1199 
1200 
1201 	private void printResultSet(ResultSet rs, PrintStream out) throws SQLException {
1202 		if (rs != null) {
1203 			getLog().debug("Processing new result set.");
1204 			ResultSetMetaData md = rs.getMetaData();
1205 			int columnCount = md.getColumnCount();
1206 			StringBuffer line = new StringBuffer();
1207 			if (showheaders) {
1208 				boolean first = true;
1209 				for (int col = 1; col <= columnCount; col++) {
1210 					String columnValue = md.getColumnName(col);
1211 
1212 					if (columnValue != null) {
1213 						columnValue = columnValue.trim();
1214 
1215 						if (",".equals(outputDelimiter)) {
1216 							columnValue = StringEscapeUtils.escapeCsv(columnValue);
1217 						}
1218 					}
1219 
1220 					if (first) {
1221 						first = false;
1222 					} else {
1223 						line.append(outputDelimiter);
1224 					}
1225 					line.append(columnValue);
1226 				}
1227 				out.println(line);
1228 				line = new StringBuffer();
1229 			}
1230 			while (rs.next()) {
1231 				boolean first = true;
1232 				for (int col = 1; col <= columnCount; col++) {
1233 					String columnValue = rs.getString(col);
1234 					if (columnValue != null) {
1235 						columnValue = columnValue.trim();
1236 
1237 						if (",".equals(outputDelimiter)) {
1238 							columnValue = StringEscapeUtils.escapeCsv(columnValue);
1239 						}
1240 					}
1241 
1242 					if (first) {
1243 						first = false;
1244 					} else {
1245 						line.append(outputDelimiter);
1246 					}
1247 					line.append(columnValue);
1248 				}
1249 				out.println(line);
1250 				line = new StringBuffer();
1251 			}
1252 		}
1253 		out.println();
1254 	}
1255 
1256 	
1257 
1258 
1259 
1260 	protected class Transaction implements Comparable<Transaction> {
1261 
1262 		protected SqlResource resource = null;
1263 
1264 		protected File tSrcFile = null;
1265 
1266 		protected String tSqlCommand = "";
1267 
1268 		
1269 
1270 
1271 		public void setResource(SqlResource resource) {
1272 			this.resource = resource;
1273 		}
1274 
1275 		
1276 
1277 
1278 		public void setSrc(File src) {
1279 			this.tSrcFile = src;
1280 		}
1281 
1282 		
1283 
1284 
1285 		public void addText(String sql) {
1286 			this.tSqlCommand += sql;
1287 		}
1288 
1289 		
1290 
1291 
1292 		private void runTransaction(PrintStream out) throws IOException, SQLException {
1293 			if (tSqlCommand.length() != 0) {
1294 				getLog().info("Executing commands");
1295 
1296 				runStatements(new StringReader(tSqlCommand), out);
1297 			}
1298 
1299 			if (tSrcFile != null) {
1300 				getLog().info("Executing file - " + tSrcFile.getAbsolutePath());
1301 
1302 				Reader reader = null;
1303 
1304 				if (StringUtils.isEmpty(encoding)) {
1305 					reader = new FileReader(tSrcFile);
1306 				} else {
1307 					reader = new InputStreamReader(new FileInputStream(tSrcFile), encoding);
1308 				}
1309 
1310 				try {
1311 					runStatements(reader, out);
1312 				} finally {
1313 					IOUtils.closeQuietly(reader);
1314 				}
1315 			}
1316 
1317 			if (resource != null) {
1318 				getLog().info("Executing - [" + resource.getLocation() + "]");
1319 				getLog().debug("Location - [" + getURL(resource.getResource()) + "]");
1320 
1321 				Reader reader = null;
1322 
1323 				if (StringUtils.isEmpty(encoding)) {
1324 					reader = new InputStreamReader(resource.getResource().getInputStream());
1325 				} else {
1326 					reader = new InputStreamReader(resource.getResource().getInputStream(), encoding);
1327 				}
1328 
1329 				try {
1330 					runStatements(reader, out);
1331 				} finally {
1332 					IOUtils.closeQuietly(reader);
1333 				}
1334 			}
1335 		}
1336 
1337 		@Override
1338 		public int compareTo(Transaction transaction) {
1339 
1340 			if (transaction.tSrcFile == null) {
1341 				if (this.tSrcFile == null) {
1342 					return 0;
1343 				} else {
1344 					return Integer.MAX_VALUE;
1345 				}
1346 			} else {
1347 				if (this.tSrcFile == null) {
1348 					return Integer.MIN_VALUE;
1349 				} else {
1350 					return this.tSrcFile.compareTo(transaction.tSrcFile);
1351 				}
1352 			}
1353 		}
1354 	}
1355 
1356 	
1357 	
1358 	
1359 
1360 	public String getUsername() {
1361 		return this.username;
1362 	}
1363 
1364 	public void setUsername(String username) {
1365 		this.username = username;
1366 	}
1367 
1368 	public String getPassword() {
1369 		return this.password;
1370 	}
1371 
1372 	public void setPassword(String password) {
1373 		this.password = password;
1374 	}
1375 
1376 	public String getUrl() {
1377 		return this.url;
1378 	}
1379 
1380 	public void setUrl(String url) {
1381 		this.url = url;
1382 	}
1383 
1384 	public String getDriver() {
1385 		return this.driver;
1386 	}
1387 
1388 	public void setDriver(String driver) {
1389 		this.driver = driver;
1390 	}
1391 
1392 	void setAutocommit(boolean autocommit) {
1393 		this.autocommit = autocommit;
1394 	}
1395 
1396 	void setFileset(Fileset fileset) {
1397 		this.fileset = fileset;
1398 	}
1399 
1400 	public File[] getSrcFiles() {
1401 		return this.srcFiles;
1402 	}
1403 
1404 	public void setSrcFiles(File[] files) {
1405 		this.srcFiles = files;
1406 	}
1407 
1408 	
1409 
1410 
1411 	@Deprecated
1412 	int getGoodSqls() {
1413 		return this.getSuccessfulStatements();
1414 	}
1415 
1416 	
1417 
1418 
1419 
1420 
1421 	public int getSuccessfulStatements() {
1422 		return successfulStatements;
1423 	}
1424 
1425 	
1426 
1427 
1428 
1429 
1430 	public int getTotalStatements() {
1431 		return totalStatements;
1432 	}
1433 
1434 	public String getOnError() {
1435 		return this.onError;
1436 	}
1437 
1438 	public void setOnError(String action) {
1439 		if (ON_ERROR_ABORT.equalsIgnoreCase(action)) {
1440 			this.onError = ON_ERROR_ABORT;
1441 		} else if (ON_ERROR_CONTINUE.equalsIgnoreCase(action)) {
1442 			this.onError = ON_ERROR_CONTINUE;
1443 		} else if (ON_ERROR_ABORT_AFTER.equalsIgnoreCase(action)) {
1444 			this.onError = ON_ERROR_ABORT_AFTER;
1445 		} else {
1446 			throw new IllegalArgumentException(action + " is not a valid value for onError, only '" + ON_ERROR_ABORT + "', '" + ON_ERROR_ABORT_AFTER + "', or '"
1447 			        + ON_ERROR_CONTINUE + "'.");
1448 		}
1449 	}
1450 
1451 	void setSettings(Settings settings) {
1452 		this.settings = settings;
1453 	}
1454 
1455 	void setSettingsKey(String key) {
1456 		this.settingsKey = key;
1457 	}
1458 
1459 	void setSkip(boolean skip) {
1460 		this.skip = skip;
1461 	}
1462 
1463 	public void setDriverProperties(String driverProperties) {
1464 		this.driverProperties = driverProperties;
1465 	}
1466 
1467 	public boolean isEnableBlockMode() {
1468 		return enableBlockMode;
1469 	}
1470 
1471 	public void setEnableBlockMode(boolean enableBlockMode) {
1472 		this.enableBlockMode = enableBlockMode;
1473 	}
1474 
1475 	public String getSqlCommand() {
1476 		return sqlCommand;
1477 	}
1478 
1479 	public void setSqlCommand(String sqlCommand) {
1480 		this.sqlCommand = sqlCommand;
1481 	}
1482 
1483 	public Vector<Transaction> getTransactions() {
1484 		return transactions;
1485 	}
1486 
1487 	public void setTransactions(Vector<Transaction> transactions) {
1488 		this.transactions = transactions;
1489 	}
1490 
1491 	public void setFileFilter(MavenFileFilter filter) {
1492 		this.fileFilter = filter;
1493 	}
1494 
1495 	public String[] getResourceLocations() {
1496 		return resourceLocations;
1497 	}
1498 
1499 	public void setResourceLocations(String[] resourceLocations) {
1500 		this.resourceLocations = resourceLocations;
1501 	}
1502 
1503 	public boolean isExecuteTrailingSQL() {
1504 		return executeTrailingSQL;
1505 	}
1506 
1507 	public void setExecuteTrailingSQL(boolean executeTrailingSQL) {
1508 		this.executeTrailingSQL = executeTrailingSQL;
1509 	}
1510 
1511 	public Order getOrderFile() {
1512 		return orderFile;
1513 	}
1514 
1515 	public void setOrderFile(String orderFile) {
1516 		this.orderFile = Order.valueOf(orderFile.toUpperCase());
1517 	}
1518 
1519 	public String getResourceListingLocation() {
1520 		return resourceListingLocation;
1521 	}
1522 
1523 	public void setResourceListingLocation(String resourceListingLocation) {
1524 		this.resourceListingLocation = resourceListingLocation;
1525 	}
1526 }