1 | |
package liquibase.executor; |
2 | |
|
3 | |
import java.io.IOException; |
4 | |
import java.io.Writer; |
5 | |
import java.util.ArrayList; |
6 | |
import java.util.List; |
7 | |
import java.util.Map; |
8 | |
|
9 | |
import liquibase.database.Database; |
10 | |
import liquibase.database.core.MSSQLDatabase; |
11 | |
import liquibase.database.core.SybaseASADatabase; |
12 | |
import liquibase.database.core.SybaseDatabase; |
13 | |
import liquibase.exception.DatabaseException; |
14 | |
import liquibase.servicelocator.LiquibaseService; |
15 | |
import liquibase.sql.visitor.SqlVisitor; |
16 | |
import liquibase.sqlgenerator.SqlGeneratorFactory; |
17 | |
import liquibase.statement.CallableSqlStatement; |
18 | |
import liquibase.statement.SqlStatement; |
19 | |
import liquibase.statement.core.GetNextChangeSetSequenceValueStatement; |
20 | |
import liquibase.statement.core.LockDatabaseChangeLogStatement; |
21 | |
import liquibase.statement.core.RawSqlStatement; |
22 | |
import liquibase.statement.core.SelectFromDatabaseChangeLogLockStatement; |
23 | |
import liquibase.statement.core.UnlockDatabaseChangeLogStatement; |
24 | |
import liquibase.util.StreamUtil; |
25 | |
|
26 | |
@LiquibaseService(skip = true) |
27 | |
public class LoggingExecutor extends AbstractExecutor implements Executor { |
28 | |
|
29 | |
private Writer output; |
30 | |
private Executor delegatedReadExecutor; |
31 | |
|
32 | 0 | public LoggingExecutor(Executor delegatedExecutor, Writer output, Database database) { |
33 | 0 | this.output = output; |
34 | 0 | this.delegatedReadExecutor = delegatedExecutor; |
35 | 0 | setDatabase(database); |
36 | 0 | } |
37 | |
|
38 | |
@Override |
39 | |
public void execute(SqlStatement sql) throws DatabaseException { |
40 | 0 | outputStatement(sql); |
41 | 0 | } |
42 | |
|
43 | |
@Override |
44 | |
public int update(SqlStatement sql) throws DatabaseException { |
45 | 0 | if (sql instanceof LockDatabaseChangeLogStatement) { |
46 | 0 | return 1; |
47 | 0 | } else if (sql instanceof UnlockDatabaseChangeLogStatement) { |
48 | 0 | return 1; |
49 | |
} |
50 | |
|
51 | 0 | outputStatement(sql); |
52 | |
|
53 | 0 | return 0; |
54 | |
} |
55 | |
|
56 | |
@Override |
57 | |
public void execute(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException { |
58 | 0 | outputStatement(sql, sqlVisitors); |
59 | 0 | } |
60 | |
|
61 | |
@Override |
62 | |
public int update(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException { |
63 | 0 | outputStatement(sql, sqlVisitors); |
64 | 0 | return 0; |
65 | |
} |
66 | |
|
67 | |
@Override |
68 | |
public Map call(CallableSqlStatement csc, List declaredParameters, List<SqlVisitor> sqlVisitors) |
69 | |
throws DatabaseException { |
70 | 0 | throw new DatabaseException("Do not know how to output callable statement"); |
71 | |
} |
72 | |
|
73 | |
@Override |
74 | |
public void comment(String message) throws DatabaseException { |
75 | |
try { |
76 | 0 | output.write(database.getLineComment()); |
77 | 0 | output.write(" "); |
78 | 0 | output.write(message); |
79 | 0 | output.write(StreamUtil.getLineSeparator()); |
80 | 0 | } catch (IOException e) { |
81 | 0 | throw new DatabaseException(e); |
82 | 0 | } |
83 | 0 | } |
84 | |
|
85 | |
private void outputStatement(SqlStatement sql) throws DatabaseException { |
86 | 0 | outputStatement(sql, new ArrayList<SqlVisitor>()); |
87 | 0 | } |
88 | |
|
89 | |
private void outputStatement(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException { |
90 | |
try { |
91 | 0 | if (SqlGeneratorFactory.getInstance().requiresCurrentDatabaseMetadata(sql, database)) { |
92 | 0 | throw new DatabaseException(sql.getClass().getSimpleName() |
93 | |
+ " requires access to up to date database metadata which is not available in SQL output mode"); |
94 | |
} |
95 | 0 | for (String statement : applyVisitors(sql, sqlVisitors)) { |
96 | 0 | if (statement == null) { |
97 | 0 | continue; |
98 | |
} |
99 | 0 | output.write(statement); |
100 | |
|
101 | 0 | if (database instanceof MSSQLDatabase || database instanceof SybaseDatabase |
102 | |
|| database instanceof SybaseASADatabase) { |
103 | 0 | output.write(StreamUtil.getLineSeparator()); |
104 | 0 | output.write("GO"); |
105 | |
|
106 | |
|
107 | |
|
108 | |
} else { |
109 | 0 | String endDelimiter = ";"; |
110 | 0 | if (sql instanceof RawSqlStatement) { |
111 | 0 | endDelimiter = ((RawSqlStatement) sql).getEndDelimiter(); |
112 | |
} |
113 | 0 | if (!statement.endsWith(endDelimiter)) { |
114 | 0 | output.write(endDelimiter); |
115 | |
} |
116 | |
} |
117 | 0 | output.write(StreamUtil.getLineSeparator()); |
118 | 0 | output.write(StreamUtil.getLineSeparator()); |
119 | |
} |
120 | 0 | } catch (IOException e) { |
121 | 0 | throw new DatabaseException(e); |
122 | 0 | } |
123 | 0 | } |
124 | |
|
125 | |
@Override |
126 | |
public Object queryForObject(SqlStatement sql, Class requiredType) throws DatabaseException { |
127 | 0 | if (sql instanceof SelectFromDatabaseChangeLogLockStatement) { |
128 | 0 | return false; |
129 | |
} |
130 | 0 | return delegatedReadExecutor.queryForObject(sql, requiredType); |
131 | |
} |
132 | |
|
133 | |
@Override |
134 | |
public Object queryForObject(SqlStatement sql, Class requiredType, List<SqlVisitor> sqlVisitors) |
135 | |
throws DatabaseException { |
136 | 0 | return delegatedReadExecutor.queryForObject(sql, requiredType, sqlVisitors); |
137 | |
} |
138 | |
|
139 | |
@Override |
140 | |
public long queryForLong(SqlStatement sql) throws DatabaseException { |
141 | 0 | return delegatedReadExecutor.queryForLong(sql); |
142 | |
} |
143 | |
|
144 | |
@Override |
145 | |
public long queryForLong(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException { |
146 | 0 | return delegatedReadExecutor.queryForLong(sql, sqlVisitors); |
147 | |
} |
148 | |
|
149 | |
@Override |
150 | |
public int queryForInt(SqlStatement sql) throws DatabaseException { |
151 | |
try { |
152 | 0 | return delegatedReadExecutor.queryForInt(sql); |
153 | 0 | } catch (DatabaseException e) { |
154 | 0 | if (sql instanceof GetNextChangeSetSequenceValueStatement) { |
155 | 0 | return 0; |
156 | |
} |
157 | 0 | throw e; |
158 | |
} |
159 | |
} |
160 | |
|
161 | |
@Override |
162 | |
public int queryForInt(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException { |
163 | 0 | return delegatedReadExecutor.queryForInt(sql, sqlVisitors); |
164 | |
} |
165 | |
|
166 | |
@Override |
167 | |
public List queryForList(SqlStatement sql, Class elementType) throws DatabaseException { |
168 | 0 | return delegatedReadExecutor.queryForList(sql, elementType); |
169 | |
} |
170 | |
|
171 | |
@Override |
172 | |
public List queryForList(SqlStatement sql, Class elementType, List<SqlVisitor> sqlVisitors) |
173 | |
throws DatabaseException { |
174 | 0 | return delegatedReadExecutor.queryForList(sql, elementType, sqlVisitors); |
175 | |
} |
176 | |
|
177 | |
@Override |
178 | |
public List<Map> queryForList(SqlStatement sql) throws DatabaseException { |
179 | 0 | return delegatedReadExecutor.queryForList(sql); |
180 | |
} |
181 | |
|
182 | |
@Override |
183 | |
public List<Map> queryForList(SqlStatement sql, List<SqlVisitor> sqlVisitors) throws DatabaseException { |
184 | 0 | return delegatedReadExecutor.queryForList(sql, sqlVisitors); |
185 | |
} |
186 | |
|
187 | |
@Override |
188 | |
public boolean updatesDatabase() { |
189 | 0 | return false; |
190 | |
} |
191 | |
} |