1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package com.rapiddweller.platform.db;
28
29 import com.rapiddweller.common.LogCategoriesConstants;
30 import com.rapiddweller.common.OrderedMap;
31 import com.rapiddweller.jdbacl.ColumnInfo;
32 import com.rapiddweller.jdbacl.DBUtil;
33 import com.rapiddweller.jdbacl.model.DBTable;
34 import com.rapiddweller.model.data.ComplexTypeDescriptor;
35 import org.apache.logging.log4j.LogManager;
36 import org.apache.logging.log4j.Logger;
37
38 import java.io.Closeable;
39 import java.sql.Connection;
40 import java.sql.PreparedStatement;
41 import java.sql.SQLException;
42 import java.util.List;
43 import java.util.Map;
44
45
46
47
48
49
50
51
52 public class ConnectionHolder implements Closeable {
53
54 private static final Logger JDBC_LOGGER =
55 LogManager.getLogger(LogCategoriesConstants.JDBC);
56
57
58
59 public final Map<ComplexTypeDescriptor, PreparedStatement> insertStatements;
60
61
62
63 public final Map<ComplexTypeDescriptor, PreparedStatement> updateStatements;
64
65
66
67 public final Map<ComplexTypeDescriptor, PreparedStatement>
68 selectByPKStatements;
69 private final DBSystem db;
70 private Connection connection;
71
72
73
74
75
76
77 public ConnectionHolder(DBSystem db) {
78 this.insertStatements = new OrderedMap<>();
79 this.updateStatements = new OrderedMap<>();
80 this.selectByPKStatements = new OrderedMap<>();
81 this.db = db;
82 this.connection = null;
83 }
84
85
86
87
88
89
90 public Connection getConnection() {
91 if (connection == null) {
92 this.connection = db.createConnection();
93 }
94 return connection;
95 }
96
97
98
99
100 public void commit() {
101 try {
102 flushStatements(insertStatements);
103 flushStatements(updateStatements);
104 JDBC_LOGGER.debug("Committing connection: {}", connection);
105 getConnection().commit();
106 } catch (SQLException e) {
107 throw new RuntimeException(e);
108 }
109 }
110
111 private void flushStatements(
112 Map<ComplexTypeDescriptor, PreparedStatement> statements)
113 throws SQLException {
114 for (Map.Entry<ComplexTypeDescriptor, PreparedStatement> entry : statements
115 .entrySet()) {
116 PreparedStatement statement = entry.getValue();
117 if (statement != null) {
118
119 if (db.isBatch()) {
120 statement.executeBatch();
121 }
122 JDBC_LOGGER.debug("Closing statement: {}", statement);
123 DBUtil.close(statement);
124 }
125 entry.setValue(null);
126 }
127 }
128
129
130
131
132
133
134
135 public PreparedStatement getSelectByPKStatement(
136 ComplexTypeDescriptor descriptor) {
137 try {
138 PreparedStatement statement = selectByPKStatements.get(descriptor);
139 if (statement == null) {
140 statement = createSelectByPKStatement(descriptor);
141 } else {
142 statement.clearParameters();
143 }
144 return statement;
145 } catch (SQLException e) {
146 throw new RuntimeException(e);
147 }
148 }
149
150 private PreparedStatement createSelectByPKStatement(
151 ComplexTypeDescriptor descriptor) throws SQLException {
152 PreparedStatement statement;
153 String tableName = descriptor.getName();
154 DBTable table = db.getTable(tableName.toUpperCase());
155 if (table == null) {
156 throw new IllegalArgumentException("Table not found: " + tableName);
157 }
158 StringBuilder builder =
159 new StringBuilder("select * from ").append(tableName)
160 .append(" where");
161 for (String idColumnName : descriptor.getIdComponentNames()) {
162 builder.append(' ').append(idColumnName).append("=?");
163 }
164 statement = DBUtil.prepareStatement(getConnection(), builder.toString(),
165 db.isReadOnly());
166 selectByPKStatements.put(descriptor, statement);
167 return statement;
168 }
169
170
171
172
173
174
175
176
177
178 public PreparedStatement getStatement(ComplexTypeDescriptor descriptor,
179 boolean insert,
180 List<ColumnInfo> columnInfos) {
181 try {
182 PreparedStatement statement =
183 (insert ? insertStatements.get(descriptor) :
184 updateStatements.get(descriptor));
185 if (statement == null) {
186 statement = createStatement(descriptor, insert, columnInfos);
187 } else {
188 statement.clearParameters();
189 }
190 return statement;
191 } catch (SQLException e) {
192 throw new RuntimeException(e);
193 }
194 }
195
196 private PreparedStatement createStatement(ComplexTypeDescriptor descriptor,
197 boolean insert,
198 List<ColumnInfo> columnInfos)
199 throws SQLException {
200 PreparedStatement statement;
201 String tableName = descriptor.getName();
202 DBTable table = db.getTable(tableName.toUpperCase());
203 if (table == null) {
204 throw new IllegalArgumentException("Table not found: " + tableName);
205 }
206 String sql = (insert ?
207 db.getDialect().insert(table, columnInfos) :
208 db.getDialect().update(table,
209 db.getTable(tableName).getPKColumnNames(),
210 columnInfos));
211 JDBC_LOGGER.debug("Creating prepared statement: {}", sql);
212 statement =
213 DBUtil.prepareStatement(getConnection(), sql, db.isReadOnly());
214 if (insert) {
215 insertStatements.put(descriptor, statement);
216 } else {
217 updateStatements.put(descriptor, statement);
218 }
219 return statement;
220 }
221
222 @Override
223 public void close() {
224 commit();
225 DBUtil.close(connection);
226 }
227
228 }