1 | |
package liquibase.sqlgenerator.core; |
2 | |
|
3 | |
import java.util.Arrays; |
4 | |
import liquibase.database.Database; |
5 | |
import liquibase.database.typeconversion.TypeConverterFactory; |
6 | |
import liquibase.exception.LiquibaseException; |
7 | |
import liquibase.exception.ValidationErrors; |
8 | |
import liquibase.sqlgenerator.SqlGeneratorChain; |
9 | |
import liquibase.statement.core.InsertOrUpdateStatement; |
10 | |
import liquibase.statement.core.UpdateStatement; |
11 | |
import liquibase.sql.Sql; |
12 | |
import liquibase.sql.UnparsedSql; |
13 | |
|
14 | |
import java.util.Date; |
15 | |
import java.util.HashSet; |
16 | |
|
17 | 55 | public abstract class InsertOrUpdateGenerator extends AbstractSqlGenerator<InsertOrUpdateStatement> { |
18 | |
|
19 | |
protected abstract String getRecordCheck(InsertOrUpdateStatement insertOrUpdateStatement, Database database, |
20 | |
String whereClause); |
21 | |
|
22 | |
protected abstract String getElse(Database database); |
23 | |
|
24 | |
protected String getPostUpdateStatements() { |
25 | 0 | return ""; |
26 | |
} |
27 | |
|
28 | |
@Override |
29 | |
public int getPriority() { |
30 | 5 | return PRIORITY_DATABASE; |
31 | |
} |
32 | |
|
33 | |
public ValidationErrors validate(InsertOrUpdateStatement statement, Database database, |
34 | |
SqlGeneratorChain sqlGeneratorChain) { |
35 | 0 | ValidationErrors validationErrors = new ValidationErrors(); |
36 | 0 | validationErrors.checkRequiredField("tableName", statement.getTableName()); |
37 | 0 | validationErrors.checkRequiredField("columns", statement.getColumnValues()); |
38 | 0 | validationErrors.checkRequiredField("primaryKey", statement.getPrimaryKey()); |
39 | |
|
40 | 0 | return validationErrors; |
41 | |
} |
42 | |
|
43 | |
protected String getWhereClause(InsertOrUpdateStatement insertOrUpdateStatement, Database database) { |
44 | 1 | StringBuffer where = new StringBuffer(); |
45 | |
|
46 | 1 | String[] pkColumns = insertOrUpdateStatement.getPrimaryKey().split(","); |
47 | |
|
48 | 2 | for (String thisPkColumn : pkColumns) { |
49 | 1 | where.append( |
50 | |
database.escapeColumnName(insertOrUpdateStatement.getSchemaName(), |
51 | |
insertOrUpdateStatement.getTableName(), thisPkColumn)).append(" = "); |
52 | 1 | Object newValue = insertOrUpdateStatement.getColumnValues().get(thisPkColumn); |
53 | 1 | if (newValue == null || newValue.toString().equals("NULL")) { |
54 | 0 | where.append("NULL"); |
55 | 1 | } else if (newValue instanceof String && database.shouldQuoteValue(((String) newValue))) { |
56 | 1 | where.append("'").append(database.escapeStringForDatabase((String) newValue)).append("'"); |
57 | 0 | } else if (newValue instanceof Date) { |
58 | 0 | where.append(database.getDateLiteral(((Date) newValue))); |
59 | 0 | } else if (newValue instanceof Boolean) { |
60 | 0 | if (((Boolean) newValue)) { |
61 | 0 | where.append(TypeConverterFactory.getInstance().findTypeConverter(database).getBooleanType() |
62 | |
.getTrueBooleanValue()); |
63 | |
} else { |
64 | 0 | where.append(TypeConverterFactory.getInstance().findTypeConverter(database).getBooleanType() |
65 | |
.getFalseBooleanValue()); |
66 | |
} |
67 | |
} else { |
68 | 0 | where.append(newValue); |
69 | |
} |
70 | |
|
71 | 1 | where.append(" AND "); |
72 | |
} |
73 | |
|
74 | 1 | where.delete(where.lastIndexOf(" AND "), where.lastIndexOf(" AND ") + " AND ".length()); |
75 | 1 | return where.toString(); |
76 | |
} |
77 | |
|
78 | |
protected String getInsertStatement(InsertOrUpdateStatement insertOrUpdateStatement, Database database, |
79 | |
SqlGeneratorChain sqlGeneratorChain) { |
80 | 2 | StringBuffer insertBuffer = new StringBuffer(); |
81 | 2 | InsertGenerator insert = new InsertGenerator(); |
82 | 2 | Sql[] insertSql = insert.generateSql(insertOrUpdateStatement, database, sqlGeneratorChain); |
83 | |
|
84 | 4 | for (Sql s : insertSql) { |
85 | 2 | insertBuffer.append(s.toSql()); |
86 | 2 | insertBuffer.append(";"); |
87 | |
} |
88 | |
|
89 | 2 | insertBuffer.append("\n"); |
90 | |
|
91 | 2 | return insertBuffer.toString(); |
92 | |
} |
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
|
102 | |
protected String getUpdateStatement(InsertOrUpdateStatement insertOrUpdateStatement, Database database, |
103 | |
String whereClause, SqlGeneratorChain sqlGeneratorChain) throws LiquibaseException { |
104 | |
|
105 | 2 | StringBuffer updateSqlString = new StringBuffer(); |
106 | |
|
107 | 2 | UpdateGenerator update = new UpdateGenerator(); |
108 | 2 | UpdateStatement updateStatement = new UpdateStatement(insertOrUpdateStatement.getSchemaName(), |
109 | |
insertOrUpdateStatement.getTableName()); |
110 | 2 | updateStatement.setWhereClause(whereClause + ";\n"); |
111 | |
|
112 | 2 | String[] pkFields = insertOrUpdateStatement.getPrimaryKey().split(","); |
113 | 2 | HashSet<String> hashPkFields = new HashSet<String>(Arrays.asList(pkFields)); |
114 | 2 | for (String columnKey : insertOrUpdateStatement.getColumnValues().keySet()) { |
115 | 3 | if (!hashPkFields.contains(columnKey)) { |
116 | 2 | updateStatement.addNewColumnValue(columnKey, insertOrUpdateStatement.getColumnValue(columnKey)); |
117 | |
} |
118 | |
} |
119 | |
|
120 | 2 | if (updateStatement.getNewColumnValues().isEmpty()) { |
121 | 0 | throw new LiquibaseException("No fields to update in set clause"); |
122 | |
} |
123 | |
|
124 | 2 | Sql[] updateSql = update.generateSql(updateStatement, database, sqlGeneratorChain); |
125 | |
|
126 | 4 | for (Sql s : updateSql) { |
127 | 2 | updateSqlString.append(s.toSql()); |
128 | 2 | updateSqlString.append(";"); |
129 | |
} |
130 | |
|
131 | 2 | updateSqlString.deleteCharAt(updateSqlString.lastIndexOf(";")); |
132 | 2 | updateSqlString.append("\n"); |
133 | |
|
134 | 2 | return updateSqlString.toString(); |
135 | |
|
136 | |
} |
137 | |
|
138 | |
public Sql[] generateSql(InsertOrUpdateStatement insertOrUpdateStatement, Database database, |
139 | |
SqlGeneratorChain sqlGeneratorChain) { |
140 | 1 | StringBuffer completeSql = new StringBuffer(); |
141 | 1 | String whereClause = getWhereClause(insertOrUpdateStatement, database); |
142 | |
|
143 | 1 | completeSql.append(getRecordCheck(insertOrUpdateStatement, database, whereClause)); |
144 | |
|
145 | 1 | completeSql.append(getInsertStatement(insertOrUpdateStatement, database, sqlGeneratorChain)); |
146 | |
|
147 | |
try { |
148 | |
|
149 | 1 | String updateStatement = getUpdateStatement(insertOrUpdateStatement, database, whereClause, |
150 | |
sqlGeneratorChain); |
151 | |
|
152 | 1 | completeSql.append(getElse(database)); |
153 | |
|
154 | 1 | completeSql.append(updateStatement); |
155 | |
|
156 | 0 | } catch (LiquibaseException e) { |
157 | 1 | } |
158 | |
|
159 | 1 | completeSql.append(getPostUpdateStatements()); |
160 | |
|
161 | 1 | return new Sql[] { new UnparsedSql(completeSql.toString()) }; |
162 | |
} |
163 | |
} |