|
24 | 24 | public class SqlQuery { |
25 | 25 | private static final Recorder recorder = Recorder.getInstance(); |
26 | 26 | private static final Map<Statement, String> statementSql = Collections.synchronizedMap(new WeakHashMap<>()); |
| 27 | + private static final Map<Statement, java.util.List<String>> statementBatchSql = Collections.synchronizedMap(new WeakHashMap<>()); |
27 | 28 |
|
28 | 29 | public static void recordSql(Event event, String databaseType, String sql) { |
29 | 30 | event.setSqlQuery(databaseType, sql); |
@@ -101,47 +102,87 @@ private static String getDbName(Statement s) { |
101 | 102 | } |
102 | 103 |
|
103 | 104 | // ================================================================================================ |
104 | | - // nativeSQL |
| 105 | + // addBatch |
105 | 106 | // ================================================================================================ |
106 | 107 |
|
107 | | - @HookClass("java.sql.Connection") |
108 | | - public static void nativeSQL(Event event, Connection c, String sql) { |
109 | | - recordSql(event, c, sql); |
| 108 | + @HookClass(value = "java.sql.PreparedStatement", methodEvent = MethodEvent.METHOD_RETURN) |
| 109 | + public static void addBatch(Event event, Statement s) { |
| 110 | + String sql = statementSql.get(s); |
| 111 | + if (sql != null) { |
| 112 | + statementBatchSql.computeIfAbsent(s, k -> new java.util.ArrayList<>()).add(sql); |
| 113 | + } |
110 | 114 | } |
111 | 115 |
|
112 | | - @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_RETURN) |
113 | | - public static void nativeSQL(Event event, Connection c, Object returnValue, String sql) { |
| 116 | + @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN) |
| 117 | + public static void addBatch(Event event, Statement s, String sql) { |
| 118 | + statementBatchSql.computeIfAbsent(s, k -> new java.util.ArrayList<>()).add(sql); |
| 119 | + } |
| 120 | + |
| 121 | + // ================================================================================================ |
| 122 | + // clearBatch |
| 123 | + // ================================================================================================ |
| 124 | + |
| 125 | + @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN) |
| 126 | + public static void clearBatch(Event event, Statement s) { |
| 127 | + statementBatchSql.remove(s); |
| 128 | + } |
| 129 | + |
| 130 | + // ================================================================================================ |
| 131 | + // executeBatch |
| 132 | + // ================================================================================================ |
| 133 | + |
| 134 | + @HookClass("java.sql.Statement") |
| 135 | + public static void executeBatch(Event event, Statement s) { |
| 136 | + recordSqlBatch(event, s); |
| 137 | + } |
| 138 | + |
| 139 | + @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN) |
| 140 | + public static void executeBatch(Event event, Statement s, Object returnValue) { |
114 | 141 | recorder.add(event); |
115 | 142 | } |
116 | 143 |
|
117 | | - @ArgumentArray |
118 | | - @HookClass(value = "java.sql.Connection", methodEvent = MethodEvent.METHOD_EXCEPTION) |
119 | | - public static void nativeSQL(Event event, Connection c, Throwable exception, Object[] args) { |
| 144 | + @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION) |
| 145 | + public static void executeBatch(Event event, Statement s, Throwable exception) { |
120 | 146 | event.setException(exception); |
121 | 147 | recorder.add(event); |
122 | 148 | } |
123 | 149 |
|
124 | 150 | // ================================================================================================ |
125 | | - // addBatch |
| 151 | + // executeLargeBatch |
126 | 152 | // ================================================================================================ |
127 | 153 |
|
128 | | - @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN) |
129 | | - public static void addBatch(Event event, Statement s, String sql) { |
130 | | - recordSql(event, s, sql); |
| 154 | + @HookClass("java.sql.Statement") |
| 155 | + public static void executeLargeBatch(Event event, Statement s) { |
| 156 | + recordSqlBatch(event, s); |
131 | 157 | } |
132 | 158 |
|
133 | 159 | @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN) |
134 | | - public static void addBatch(Event event, Statement s, Object returnValue, String sql) { |
| 160 | + public static void executeLargeBatch(Event event, Statement s, Object returnValue) { |
135 | 161 | recorder.add(event); |
136 | 162 | } |
137 | 163 |
|
138 | | - @ArgumentArray |
139 | 164 | @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION) |
140 | | - public static void addBatch(Event event, Statement s, Throwable exception, Object[] args) { |
| 165 | + public static void executeLargeBatch(Event event, Statement s, Throwable exception) { |
141 | 166 | event.setException(exception); |
142 | 167 | recorder.add(event); |
143 | 168 | } |
144 | 169 |
|
| 170 | + private static void recordSqlBatch(Event event, Statement s) { |
| 171 | + // According to the JDBC spec, calling executeBatch clears the batch |
| 172 | + // on the statement. So, we'll remove our copy of it. |
| 173 | + java.util.List<String> sqls = statementBatchSql.remove(s); |
| 174 | + String sqlToRecord; |
| 175 | + |
| 176 | + if (sqls != null && !sqls.isEmpty()) { |
| 177 | + // In order to represent the batch as a single query, we'll join |
| 178 | + // the SQL statements together. |
| 179 | + sqlToRecord = String.join(";\n", sqls); |
| 180 | + } else { |
| 181 | + sqlToRecord = "[empty batch]"; |
| 182 | + } |
| 183 | + recordSql(event, s, sqlToRecord); |
| 184 | + } |
| 185 | + |
145 | 186 | // ================================================================================================ |
146 | 187 | // execute |
147 | 188 | // ================================================================================================ |
@@ -211,6 +252,29 @@ public static void executeUpdate(Event event, Statement s, Throwable exception, |
211 | 252 | recorder.add(event); |
212 | 253 | } |
213 | 254 |
|
| 255 | + // ================================================================================================ |
| 256 | + // executeLargeUpdate |
| 257 | + // ================================================================================================ |
| 258 | + |
| 259 | + @ArgumentArray |
| 260 | + @HookClass("java.sql.Statement") |
| 261 | + public static void executeLargeUpdate(Event event, Statement s, Object[] args) { |
| 262 | + recordSql(event, s, args); |
| 263 | + } |
| 264 | + |
| 265 | + @ArgumentArray |
| 266 | + @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_RETURN) |
| 267 | + public static void executeLargeUpdate(Event event, Statement s, Object returnValue, Object[] args) { |
| 268 | + recorder.add(event); |
| 269 | + } |
| 270 | + |
| 271 | + @ArgumentArray |
| 272 | + @HookClass(value = "java.sql.Statement", methodEvent = MethodEvent.METHOD_EXCEPTION) |
| 273 | + public static void executeLargeUpdate(Event event, Statement s, Throwable exception, Object[] args) { |
| 274 | + event.setException(exception); |
| 275 | + recorder.add(event); |
| 276 | + } |
| 277 | + |
214 | 278 | // ================================================================================================ |
215 | 279 | // prepareCall |
216 | 280 | // ================================================================================================ |
|
0 commit comments