View Javadoc

1   package liquibase.change;
2   
3   import liquibase.database.Database;
4   import liquibase.database.core.MSSQLDatabase;
5   import liquibase.statement.SqlStatement;
6   import liquibase.statement.core.RawSqlStatement;
7   import liquibase.util.StringUtils;
8   
9   import java.util.ArrayList;
10  import java.util.List;
11  
12  /**
13   * A common parent for all SQL related changes regardless of where the sql was sourced from.
14   * 
15   * Implements the necessary logic to choose how it should be parsed to generate the statements.
16   * 
17   * @author <a href="mailto:csuml@yahoo.co.uk">Paul Keeble</a>
18   * 
19   */
20  public abstract class AbstractSQLChange extends AbstractChange {
21  
22      private boolean stripComments;
23      private boolean splitStatements;
24      private String endDelimiter;
25      private String sql;
26  
27      protected AbstractSQLChange(String tagName, String changeName, int priority) {
28          super(tagName, changeName, priority);
29          stripComments = false;
30          splitStatements = true;
31      }
32  
33      @Override
34      public boolean supports(Database database) {
35          return true;
36      }
37  
38      /**
39       * @param stripComments
40       *            true if comments should be stripped out, otherwise false
41       */
42      public void setStripComments(Boolean stripComments) {
43          this.stripComments = stripComments;
44      }
45  
46      /**
47       * 
48       * @return true if stripping comments, otherwise false
49       */
50      public boolean isStrippingComments() {
51          return stripComments;
52      }
53  
54      /**
55       * If set to true then the sql will be split around any ; and \ngo\n entries in the sql and each line provided as a
56       * separate statement.
57       * 
58       * @param splitStatements
59       *            set true if the SQL should be split, otherwise false
60       */
61      public void setSplitStatements(Boolean splitStatements) {
62          this.splitStatements = splitStatements;
63      }
64  
65      /**
66       * 
67       * @return true if a multi-line file will be split, otherwise false
68       */
69      public boolean isSplittingStatements() {
70          return splitStatements;
71      }
72  
73      public String getSql() {
74          return sql;
75      }
76  
77      /**
78       * The raw SQL to use for this change.
79       */
80      public void setSql(String sql) {
81          this.sql = StringUtils.trimToNull(sql);
82      }
83  
84      public String getEndDelimiter() {
85          return endDelimiter;
86      }
87  
88      public void setEndDelimiter(String endDelimiter) {
89          this.endDelimiter = endDelimiter;
90      }
91  
92      /**
93       * Generates one or more statements depending on how the SQL should be parsed. If split statements is set to true
94       * then the SQL is split on the ; and go\n entries found in the sql text and each is made a separate statement.
95       * 
96       * If stripping comments is true then any comments after -- on a line and any comments between /* and \*\/ will be
97       * stripped before the splitting is executed.
98       * 
99       * The end result is one or more SQL statements split in the way the user requested
100      */
101     public SqlStatement[] generateStatements(Database database) {
102 
103         List<SqlStatement> returnStatements = new ArrayList<SqlStatement>();
104 
105         if (StringUtils.trimToNull(getSql()) == null) {
106             return new SqlStatement[0];
107         }
108 
109         String processedSQL = getSql().replaceAll("\r\n", "\n").replaceAll("\r", "\n");
110         for (String statement : StringUtils.processMutliLineSQL(processedSQL, isStrippingComments(),
111                 isSplittingStatements(), getEndDelimiter())) {
112             if (database instanceof MSSQLDatabase) {
113                 statement = statement.replaceAll("\n", "\r\n");
114             }
115 
116             returnStatements.add(new RawSqlStatement(statement, getEndDelimiter()));
117         }
118 
119         return returnStatements.toArray(new SqlStatement[returnStatements.size()]);
120     }
121 }